mirror of
https://github.com/mauiaaron/apple2.git
synced 2025-03-24 11:30:10 +00:00
Refactor video/display rendering
- Import NTSC video display modes - Migrate to using full-color framebuffers - Mac and Android builds somewhat working - TODO : likely breaks display testing
This commit is contained in:
parent
8757cb2a06
commit
227098ec52
@ -208,7 +208,7 @@ public class Apple2Preferences {
|
||||
switch (key) {
|
||||
|
||||
case "HIRES_COLOR": // long
|
||||
menuEnum = Apple2VideoSettingsMenu.SETTINGS.COLOR_CONFIGURE;
|
||||
menuEnum = Apple2VideoSettingsMenu.SETTINGS.COLOR_MODE_CONFIGURE;
|
||||
break;
|
||||
case "LANDSCAPE_MODE": // bool
|
||||
menuEnum = Apple2VideoSettingsMenu.SETTINGS.LANDSCAPE_MODE;
|
||||
|
@ -56,10 +56,18 @@ public class Apple2VideoSettingsMenu extends Apple2AbstractMenu {
|
||||
return true;
|
||||
}
|
||||
|
||||
public enum HiresColor {
|
||||
BW,
|
||||
COLOR,
|
||||
INTERPOLATED
|
||||
public enum ColorMode {
|
||||
COLOR_MODE_MONO,
|
||||
COLOR_MODE_COLOR,
|
||||
COLOR_MODE_INTERP,
|
||||
COLOR_MODE_COLOR_MONITOR,
|
||||
COLOR_MODE_MONO_TV,
|
||||
COLOR_MODE_COLOR_TV,
|
||||
}
|
||||
|
||||
public enum MonoMode {
|
||||
MONO_MODE_BW,
|
||||
MONO_MODE_GREEN,
|
||||
}
|
||||
|
||||
// must match interface_colorscheme_t
|
||||
@ -159,7 +167,7 @@ public class Apple2VideoSettingsMenu extends Apple2AbstractMenu {
|
||||
}
|
||||
}
|
||||
},
|
||||
COLOR_CONFIGURE {
|
||||
COLOR_MODE_CONFIGURE {
|
||||
@Override
|
||||
public final String getTitle(Apple2Activity activity) {
|
||||
return activity.getResources().getString(R.string.color_configure);
|
||||
@ -182,7 +190,103 @@ public class Apple2VideoSettingsMenu extends Apple2AbstractMenu {
|
||||
|
||||
@Override
|
||||
public Object getPrefDefault() {
|
||||
return HiresColor.INTERPOLATED.ordinal();
|
||||
return ColorMode.COLOR_MODE_COLOR_TV.ordinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(Apple2Activity activity, View convertView) {
|
||||
convertView = _basicView(activity, this, convertView);
|
||||
_addPopupIcon(activity, this, convertView);
|
||||
return convertView;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleSelection(final Apple2Activity activity, final Apple2AbstractMenu settingsMenu, boolean isChecked) {
|
||||
final Apple2AbstractMenu.IMenuEnum self = this;
|
||||
_alertDialogHandleSelection(activity, R.string.video_configure, new String[]{
|
||||
settingsMenu.mActivity.getResources().getString(R.string.color_mono),
|
||||
settingsMenu.mActivity.getResources().getString(R.string.color_color),
|
||||
settingsMenu.mActivity.getResources().getString(R.string.color_interpolated),
|
||||
settingsMenu.mActivity.getResources().getString(R.string.color_monitor),
|
||||
settingsMenu.mActivity.getResources().getString(R.string.color_tv_mono),
|
||||
settingsMenu.mActivity.getResources().getString(R.string.color_tv),
|
||||
}, new IPreferenceLoadSave() {
|
||||
@Override
|
||||
public int intValue() {
|
||||
return (int) Apple2Preferences.getJSONPref(self);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveInt(int value) {
|
||||
Apple2Preferences.setJSONPref(self, ColorMode.values()[value].ordinal());
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
SHOW_HALF_SCANLINES {
|
||||
@Override
|
||||
public final String getTitle(Apple2Activity activity) {
|
||||
return activity.getResources().getString(R.string.show_half_scanlines);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getSummary(Apple2Activity activity) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrefDomain() {
|
||||
return Apple2Preferences.PREF_DOMAIN_VIDEO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrefKey() {
|
||||
return "showHalfScanlines";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPrefDefault() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(final Apple2Activity activity, View convertView) {
|
||||
final IMenuEnum self = this;
|
||||
convertView = _basicView(activity, this, convertView);
|
||||
CheckBox cb = _addCheckbox(activity, this, convertView, (boolean) Apple2Preferences.getJSONPref(this));
|
||||
cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
Apple2Preferences.setJSONPref(self, isChecked);
|
||||
}
|
||||
});
|
||||
return convertView;
|
||||
}
|
||||
},
|
||||
MONO_MODE_CONFIGURE {
|
||||
@Override
|
||||
public final String getTitle(Apple2Activity activity) {
|
||||
return activity.getResources().getString(R.string.mono_configure);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String getSummary(Apple2Activity activity) {
|
||||
return activity.getResources().getString(R.string.mono_configure_summary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrefDomain() {
|
||||
return Apple2Preferences.PREF_DOMAIN_VIDEO;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPrefKey() {
|
||||
return "monoMode";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPrefDefault() {
|
||||
return MonoMode.MONO_MODE_BW.ordinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -197,8 +301,7 @@ public class Apple2VideoSettingsMenu extends Apple2AbstractMenu {
|
||||
final Apple2AbstractMenu.IMenuEnum self = this;
|
||||
_alertDialogHandleSelection(activity, R.string.video_configure, new String[]{
|
||||
settingsMenu.mActivity.getResources().getString(R.string.color_bw),
|
||||
settingsMenu.mActivity.getResources().getString(R.string.color_color),
|
||||
settingsMenu.mActivity.getResources().getString(R.string.color_interpolated),
|
||||
settingsMenu.mActivity.getResources().getString(R.string.color_green),
|
||||
}, new IPreferenceLoadSave() {
|
||||
@Override
|
||||
public int intValue() {
|
||||
@ -207,7 +310,7 @@ public class Apple2VideoSettingsMenu extends Apple2AbstractMenu {
|
||||
|
||||
@Override
|
||||
public void saveInt(int value) {
|
||||
Apple2Preferences.setJSONPref(self, HiresColor.values()[value].ordinal());
|
||||
Apple2Preferences.setJSONPref(self, MonoMode.values()[value].ordinal());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -162,8 +162,8 @@
|
||||
<string name="touch_menu_enable_summary">Aktiviere Softmenü Knöpfe in den oberen Ecken des Bildschirms</string>
|
||||
<string name="video_configure">Video-Konfiguration…</string>
|
||||
<string name="video_configure_summary">Farbeinstellungen</string>
|
||||
<string name="color_configure">Configure color</string>
|
||||
<string name="color_configure_summary">Color mode</string>
|
||||
<string name="color_configure">Display mode</string>
|
||||
<string name="color_configure_summary">Video display emulation mode</string>
|
||||
<string name="joystick_azimuth_visible">Show joystick/keypad heading</string>
|
||||
<string name="joystick_azimuth_visible_summary">Shows current axis direction and magnitude</string>
|
||||
<string name="mode_landscape">Landscape</string>
|
||||
@ -188,5 +188,13 @@
|
||||
<string name="color_green_on_black">Green on black</string>
|
||||
<string name="color_blue_on_black">Blue on black</string>
|
||||
<string name="color_white_on_black">White on black</string>
|
||||
<string name="color_monitor">Color Monitor</string>
|
||||
<string name="color_tv_mono">Monochrome TV</string>
|
||||
<string name="color_tv">Color TV</string>
|
||||
<string name="show_half_scanlines">Show half scanlines</string>
|
||||
<string name="mono_configure">Monocolor mode</string>
|
||||
<string name="mono_configure_summary">Configure monochrome color</string>
|
||||
<string name="color_green">Green screen</string>
|
||||
<string name="color_mono">Monochrome</string>
|
||||
|
||||
</resources>
|
||||
|
@ -160,8 +160,8 @@
|
||||
<string name="touch_menu_enable_summary">Los botones del menú en la parte superior de la pantalla</string>
|
||||
<string name="video_configure">Configurar el video…</string>
|
||||
<string name="video_configure_summary">Ajustes de color</string>
|
||||
<string name="color_configure">Configure color</string>
|
||||
<string name="color_configure_summary">Color mode</string>
|
||||
<string name="color_configure">Display mode</string>
|
||||
<string name="color_configure_summary">Video display emulation mode</string>
|
||||
<string name="joystick_azimuth_visible">Show joystick/keypad heading</string>
|
||||
<string name="joystick_azimuth_visible_summary">Shows current axis direction and magnitude</string>
|
||||
<string name="mode_landscape">Landscape</string>
|
||||
@ -188,5 +188,13 @@
|
||||
<string name="color_green_on_black">Green on black</string>
|
||||
<string name="color_blue_on_black">Blue on black</string>
|
||||
<string name="color_white_on_black">White on black</string>
|
||||
<string name="color_monitor">Color Monitor</string>
|
||||
<string name="color_tv_mono">Monochrome TV</string>
|
||||
<string name="color_tv">Color TV</string>
|
||||
<string name="show_half_scanlines">Show half scanlines</string>
|
||||
<string name="mono_configure">Monocolor mode</string>
|
||||
<string name="mono_configure_summary">Configure monochrome color</string>
|
||||
<string name="color_green">Green screen</string>
|
||||
<string name="color_mono">Monochrome</string>
|
||||
|
||||
</resources>
|
||||
|
@ -160,8 +160,8 @@
|
||||
<string name="touch_menu_enable_summary">Activation soft des bouton du menu dans les coins en haut de l\'écran</string>
|
||||
<string name="video_configure">Configuration de la vidéo…</string>
|
||||
<string name="video_configure_summary">Configuration des couleurs</string>
|
||||
<string name="color_configure">Configure color</string>
|
||||
<string name="color_configure_summary">Color mode</string>
|
||||
<string name="color_configure">Display mode</string>
|
||||
<string name="color_configure_summary">Video display emulation mode</string>
|
||||
<string name="joystick_azimuth_visible">Show joystick/keypad heading</string>
|
||||
<string name="joystick_azimuth_visible_summary">Shows current axis direction and magnitude</string>
|
||||
<string name="mode_landscape">Landscape</string>
|
||||
@ -188,5 +188,13 @@
|
||||
<string name="color_green_on_black">Green on black</string>
|
||||
<string name="color_blue_on_black">Blue on black</string>
|
||||
<string name="color_white_on_black">White on black</string>
|
||||
<string name="color_monitor">Color Monitor</string>
|
||||
<string name="color_tv_mono">Monochrome TV</string>
|
||||
<string name="color_tv">Color TV</string>
|
||||
<string name="show_half_scanlines">Show half scanlines</string>
|
||||
<string name="mono_configure">Monocolor mode</string>
|
||||
<string name="mono_configure_summary">Configure monochrome color</string>
|
||||
<string name="color_green">Green screen</string>
|
||||
<string name="color_mono">Monochrome</string>
|
||||
|
||||
</resources>
|
||||
|
@ -25,8 +25,8 @@
|
||||
<string name="audio_latency">Audio latency</string>
|
||||
<string name="audio_latency_summary">Audio latency in secs</string>
|
||||
<string name="cancel">Cancel</string>
|
||||
<string name="color_configure">Configure color</string>
|
||||
<string name="color_configure_summary">Color mode</string>
|
||||
<string name="color_configure">Display mode</string>
|
||||
<string name="color_configure_summary">Video display emulation mode</string>
|
||||
<string name="color_bw">Black/white</string>
|
||||
<string name="color_color">Color</string>
|
||||
<string name="color_interpolated">Interpolated color</string>
|
||||
@ -188,5 +188,13 @@
|
||||
<string name="color_green_on_black">Green on black</string>
|
||||
<string name="color_blue_on_black">Blue on black</string>
|
||||
<string name="color_white_on_black">White on black</string>
|
||||
<string name="color_monitor">Color Monitor</string>
|
||||
<string name="color_tv_mono">Monochrome TV</string>
|
||||
<string name="color_tv">Color TV</string>
|
||||
<string name="show_half_scanlines">Show half scanlines</string>
|
||||
<string name="mono_configure">Monocolor mode</string>
|
||||
<string name="mono_configure_summary">Configure monochrome color</string>
|
||||
<string name="color_green">Green screen</string>
|
||||
<string name="color_mono">Monochrome</string>
|
||||
|
||||
</resources>
|
||||
|
@ -21,6 +21,7 @@ APPLE2_VIDEO_SRC = \
|
||||
$(APPLE2_SRC_PATH)/video/gltouchkbd.c \
|
||||
$(APPLE2_SRC_PATH)/video/gltouchmenu.c \
|
||||
$(APPLE2_SRC_PATH)/video/glvideo.c \
|
||||
$(APPLE2_SRC_PATH)/video/ntsc.c \
|
||||
$(APPLE2_SRC_PATH)/video/video.c \
|
||||
$(APPLE2_SRC_PATH)/video_util/matrixUtil.c \
|
||||
$(APPLE2_SRC_PATH)/video_util/modelUtil.c \
|
||||
|
@ -129,6 +129,20 @@
|
||||
4A4B676D1DB47682005028A6 /* Apple2iOSTestUI-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 4A4B676B1DB47682005028A6 /* Apple2iOSTestUI-Info.plist */; };
|
||||
4A4B676E1DB488B9005028A6 /* testui.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A8A405C1D85CF1B00B460B0 /* testui.c */; };
|
||||
4A4B676F1DB488BE005028A6 /* testtrace.c in Sources */ = {isa = PBXBuildFile; fileRef = 935C55751C136F0D0013166D /* testtrace.c */; };
|
||||
4A589F782157E72B0026A73A /* ntsc.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A589F722157E72B0026A73A /* ntsc.c */; };
|
||||
4A589F792157E72B0026A73A /* ntsc.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A589F722157E72B0026A73A /* ntsc.c */; };
|
||||
4A589F7A2157E72B0026A73A /* ntsc.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A589F722157E72B0026A73A /* ntsc.c */; };
|
||||
4A589F7B2157E72B0026A73A /* ntsc.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A589F722157E72B0026A73A /* ntsc.c */; };
|
||||
4A589F7C2157E72B0026A73A /* ntsc.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A589F722157E72B0026A73A /* ntsc.c */; };
|
||||
4A589F7D2157E72B0026A73A /* ntsc.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A589F722157E72B0026A73A /* ntsc.c */; };
|
||||
4A589F7E2157E72B0026A73A /* ntsc.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A589F722157E72B0026A73A /* ntsc.c */; };
|
||||
4A589F7F2157E72B0026A73A /* ntsc.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A589F722157E72B0026A73A /* ntsc.c */; };
|
||||
4A589F802157E72B0026A73A /* ntsc.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A589F722157E72B0026A73A /* ntsc.c */; };
|
||||
4A589F812157E72B0026A73A /* ntsc.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A589F722157E72B0026A73A /* ntsc.c */; };
|
||||
4A589F822157E72B0026A73A /* ntsc.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A589F722157E72B0026A73A /* ntsc.c */; };
|
||||
4A589F832157E72B0026A73A /* ntsc.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A589F722157E72B0026A73A /* ntsc.c */; };
|
||||
4A589F842157E72B0026A73A /* ntsc.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A589F722157E72B0026A73A /* ntsc.c */; };
|
||||
4A589F85215831560026A73A /* ntsc.c in Sources */ = {isa = PBXBuildFile; fileRef = 4A589F722157E72B0026A73A /* ntsc.c */; };
|
||||
4A609CB31D725D4C0066AF38 /* external-disks in Resources */ = {isa = PBXBuildFile; fileRef = 4A609CB21D725D4C0066AF38 /* external-disks */; };
|
||||
4A6746721D848B51006520C2 /* external-disks in Resources */ = {isa = PBXBuildFile; fileRef = 4A609CB21D725D4C0066AF38 /* external-disks */; };
|
||||
4A69C1921A33DB90001579EF /* DDHidLib.framework in Copy Files (1 item) */ = {isa = PBXBuildFile; fileRef = 77C2796F1A1047AF000FE33F /* DDHidLib.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
@ -943,11 +957,13 @@
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
4A0DEA9B216135BD000A2615 /* ntsc.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ntsc.h; sourceTree = "<group>"; };
|
||||
4A2636F819FDEDB700DBFB00 /* Apple2Mac.help */ = {isa = PBXFileReference; lastKnownFileType = folder; path = Apple2Mac.help; sourceTree = "<group>"; };
|
||||
4A4B671E1DB4723F005028A6 /* Apple2iOSTestTrace.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Apple2iOSTestTrace.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
4A4B67681DB47560005028A6 /* Apple2iOSTestUI.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Apple2iOSTestUI.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
4A4B676A1DB47682005028A6 /* Apple2iOSTestTrace-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Apple2iOSTestTrace-Info.plist"; sourceTree = "<group>"; };
|
||||
4A4B676B1DB47682005028A6 /* Apple2iOSTestUI-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Apple2iOSTestUI-Info.plist"; sourceTree = "<group>"; };
|
||||
4A589F722157E72B0026A73A /* ntsc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ntsc.c; sourceTree = "<group>"; };
|
||||
4A609CB21D725D4C0066AF38 /* external-disks */ = {isa = PBXFileReference; lastKnownFileType = folder; name = "external-disks"; path = "../external-disks"; sourceTree = "<group>"; };
|
||||
4A7EDC911AE092680072E98A /* glhudmodel.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = glhudmodel.c; sourceTree = "<group>"; };
|
||||
4A7EDC921AE092680072E98A /* glnode.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = glnode.c; sourceTree = "<group>"; };
|
||||
@ -1542,6 +1558,8 @@
|
||||
773B3D8A19568A570085CE5F /* video */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
4A0DEA9B216135BD000A2615 /* ntsc.h */,
|
||||
4A589F722157E72B0026A73A /* ntsc.c */,
|
||||
4AEDCEF5209E9D3F0090B44F /* glinput.h */,
|
||||
4AEDCEF6209E9D3F0090B44F /* glutinput.c */,
|
||||
4AEDCEF4209E9D3F0090B44F /* ncvideo.c */,
|
||||
@ -2777,6 +2795,7 @@
|
||||
4A4B66E01DB4723F005028A6 /* A2IXPopupChoreographer.m in Sources */,
|
||||
4A4B676F1DB488BE005028A6 /* testtrace.c in Sources */,
|
||||
4A4B66E11DB4723F005028A6 /* gltouchjoy_kpad.c in Sources */,
|
||||
4A589F822157E72B0026A73A /* ntsc.c in Sources */,
|
||||
4A4B66E21DB4723F005028A6 /* gltouchjoy.c in Sources */,
|
||||
4A4B66E31DB4723F005028A6 /* soundcore.c in Sources */,
|
||||
4A4B66E41DB4723F005028A6 /* soundcore-openal.c in Sources */,
|
||||
@ -2836,6 +2855,7 @@
|
||||
4A4B672A1DB47560005028A6 /* A2IXPopupChoreographer.m in Sources */,
|
||||
4A4B672B1DB47560005028A6 /* gltouchjoy_kpad.c in Sources */,
|
||||
4A4B672C1DB47560005028A6 /* gltouchjoy.c in Sources */,
|
||||
4A589F832157E72B0026A73A /* ntsc.c in Sources */,
|
||||
4A4B672D1DB47560005028A6 /* soundcore.c in Sources */,
|
||||
4A4B672E1DB47560005028A6 /* soundcore-openal.c in Sources */,
|
||||
4A4B672F1DB47560005028A6 /* opcodes.c in Sources */,
|
||||
@ -2892,6 +2912,7 @@
|
||||
4A8A401D1D85CEEE00B460B0 /* prefs.c in Sources */,
|
||||
4A8A401E1D85CEEE00B460B0 /* display.c in Sources */,
|
||||
4A8F5D181F6A1FEC00AE37B5 /* video.c in Sources */,
|
||||
4A589F7C2157E72B0026A73A /* ntsc.c in Sources */,
|
||||
4A8A401F1D85CEEE00B460B0 /* EmulatorGLView.m in Sources */,
|
||||
4A8A40201D85CEEE00B460B0 /* disk.c in Sources */,
|
||||
4A8A40211D85CEEE00B460B0 /* sha1.c in Sources */,
|
||||
@ -2943,6 +2964,7 @@
|
||||
4ABDA9941D792E8C0086A35B /* prefs.c in Sources */,
|
||||
4ABDA9951D792E8C0086A35B /* display.c in Sources */,
|
||||
4A8F5D171F6A1FEB00AE37B5 /* video.c in Sources */,
|
||||
4A589F7B2157E72B0026A73A /* ntsc.c in Sources */,
|
||||
4ABDA9961D792E8C0086A35B /* EmulatorGLView.m in Sources */,
|
||||
4ABDA9971D792E8C0086A35B /* disk.c in Sources */,
|
||||
4ABDA9981D792E8C0086A35B /* sha1.c in Sources */,
|
||||
@ -2997,6 +3019,7 @@
|
||||
4ACD73271D20A83E00123DE6 /* A2IXPopupChoreographer.m in Sources */,
|
||||
4ACD73281D20A83E00123DE6 /* gltouchjoy_kpad.c in Sources */,
|
||||
4ACD73291D20A83E00123DE6 /* gltouchjoy.c in Sources */,
|
||||
4A589F7F2157E72B0026A73A /* ntsc.c in Sources */,
|
||||
4ACD732A1D20A83E00123DE6 /* soundcore.c in Sources */,
|
||||
4ACD732B1D20A83E00123DE6 /* soundcore-openal.c in Sources */,
|
||||
4ACD732C1D20A83E00123DE6 /* opcodes.c in Sources */,
|
||||
@ -3056,6 +3079,7 @@
|
||||
4ACD73751D20AB6A00123DE6 /* gltouchjoy_joy.c in Sources */,
|
||||
4ACD73761D20AB6A00123DE6 /* A2IXPopupChoreographer.m in Sources */,
|
||||
4ACD73771D20AB6A00123DE6 /* gltouchjoy_kpad.c in Sources */,
|
||||
4A589F842157E72B0026A73A /* ntsc.c in Sources */,
|
||||
4ACD73781D20AB6A00123DE6 /* gltouchjoy.c in Sources */,
|
||||
4ACD73791D20AB6A00123DE6 /* soundcore.c in Sources */,
|
||||
4ACD737A1D20AB6A00123DE6 /* soundcore-openal.c in Sources */,
|
||||
@ -3115,6 +3139,7 @@
|
||||
4ACD73C71D20B11D00123DE6 /* A2IXPopupChoreographer.m in Sources */,
|
||||
4ACD73C81D20B11D00123DE6 /* gltouchjoy_kpad.c in Sources */,
|
||||
4ACD73C91D20B11D00123DE6 /* gltouchjoy.c in Sources */,
|
||||
4A589F802157E72B0026A73A /* ntsc.c in Sources */,
|
||||
4ACD73CA1D20B11D00123DE6 /* soundcore.c in Sources */,
|
||||
4ACD73CB1D20B11D00123DE6 /* soundcore-openal.c in Sources */,
|
||||
4ACD73CC1D20B11D00123DE6 /* opcodes.c in Sources */,
|
||||
@ -3174,6 +3199,7 @@
|
||||
4ACD742D1D26210600123DE6 /* A2IXPopupChoreographer.m in Sources */,
|
||||
4ACD742E1D26210600123DE6 /* gltouchjoy_kpad.c in Sources */,
|
||||
4ACD742F1D26210600123DE6 /* gltouchjoy.c in Sources */,
|
||||
4A589F812157E72B0026A73A /* ntsc.c in Sources */,
|
||||
4ACD74301D26210600123DE6 /* soundcore.c in Sources */,
|
||||
4ACD74311D26210600123DE6 /* soundcore-openal.c in Sources */,
|
||||
4ACD74321D26210600123DE6 /* opcodes.c in Sources */,
|
||||
@ -3230,6 +3256,7 @@
|
||||
4AD4FE951A52464F00F958EC /* prefs.c in Sources */,
|
||||
4AD4FE961A52464F00F958EC /* display.c in Sources */,
|
||||
4A8F5D151F6A1FEA00AE37B5 /* video.c in Sources */,
|
||||
4A589F792157E72B0026A73A /* ntsc.c in Sources */,
|
||||
4AA2D7E51D202A5B0054A5FF /* EmulatorGLView.m in Sources */,
|
||||
4AD4FE971A52464F00F958EC /* disk.c in Sources */,
|
||||
4AFC170C1AAE9C3200B215FA /* sha1.c in Sources */,
|
||||
@ -3281,6 +3308,7 @@
|
||||
4ADC51FF19E8CA4500186B36 /* prefs.c in Sources */,
|
||||
4ADC520019E8CA4500186B36 /* display.c in Sources */,
|
||||
4A8F5D191F6A1FED00AE37B5 /* video.c in Sources */,
|
||||
4A589F7D2157E72B0026A73A /* ntsc.c in Sources */,
|
||||
4AA2D7E61D202A5C0054A5FF /* EmulatorGLView.m in Sources */,
|
||||
4ADC520119E8CA4500186B36 /* disk.c in Sources */,
|
||||
4AFC170E1AAE9C3200B215FA /* sha1.c in Sources */,
|
||||
@ -3351,6 +3379,7 @@
|
||||
773B3DAD19568A570085CE5F /* debugger.c in Sources */,
|
||||
77E1C0B319D72700004344E0 /* vectorUtil.c in Sources */,
|
||||
4A7EDC9E1AE092B80072E98A /* interface.c in Sources */,
|
||||
4A589F85215831560026A73A /* ntsc.c in Sources */,
|
||||
773B3DAB19568A570085CE5F /* keys.c in Sources */,
|
||||
773B3DBC19568A570085CE5F /* timing.c in Sources */,
|
||||
773BC91A19F31E7B00996893 /* prefs.c in Sources */,
|
||||
@ -3399,6 +3428,7 @@
|
||||
779DD830195BD9F900DF89E5 /* prefs.c in Sources */,
|
||||
779DD831195BD9F900DF89E5 /* display.c in Sources */,
|
||||
4A8F5D141F6A1FE900AE37B5 /* video.c in Sources */,
|
||||
4A589F782157E72B0026A73A /* ntsc.c in Sources */,
|
||||
4AA2D7EC1D202BFA0054A5FF /* EmulatorGLView.m in Sources */,
|
||||
779DD832195BD9F900DF89E5 /* disk.c in Sources */,
|
||||
4AFC170B1AAE9C3200B215FA /* sha1.c in Sources */,
|
||||
@ -3450,6 +3480,7 @@
|
||||
779F566519EB0B9100A6F107 /* prefs.c in Sources */,
|
||||
779F566619EB0B9100A6F107 /* display.c in Sources */,
|
||||
4A8F5D161F6A1FEB00AE37B5 /* video.c in Sources */,
|
||||
4A589F7A2157E72B0026A73A /* ntsc.c in Sources */,
|
||||
4AA2D7E71D202A5D0054A5FF /* EmulatorGLView.m in Sources */,
|
||||
779F566719EB0B9100A6F107 /* disk.c in Sources */,
|
||||
4AFC170D1AAE9C3200B215FA /* sha1.c in Sources */,
|
||||
@ -3510,6 +3541,7 @@
|
||||
935C55631C136E070013166D /* prefs.c in Sources */,
|
||||
935C55731C136E6F0013166D /* json_parse.c in Sources */,
|
||||
935C55641C136E070013166D /* rom-shim.c in Sources */,
|
||||
4A589F7E2157E72B0026A73A /* ntsc.c in Sources */,
|
||||
935C55651C136E070013166D /* timing.c in Sources */,
|
||||
4A8F5D271F6A202100AE37B5 /* memmngt.c in Sources */,
|
||||
935C55661C136E070013166D /* glalert.c in Sources */,
|
||||
|
@ -1,8 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="10117" systemVersion="15G1004" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="14113" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none">
|
||||
<dependencies>
|
||||
<deployment version="1060" identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="14113"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
|
||||
@ -373,9 +374,10 @@ CA
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
<point key="canvasLocation" x="-608" y="-1487"/>
|
||||
</menu>
|
||||
<window title="Apple2Mac" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" releasedWhenClosed="NO" animationBehavior="default" id="371" userLabel="Window - Apple2Mac" customClass="EmulatorWindow">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES" unifiedTitleAndToolbar="YES"/>
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="200" y="200" width="568" height="384"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1920" height="1178"/>
|
||||
@ -428,7 +430,7 @@ CA
|
||||
<toolbarItem reference="85b-WO-tks"/>
|
||||
</defaultToolbarItems>
|
||||
</toolbar>
|
||||
<point key="canvasLocation" x="-308" y="-1288"/>
|
||||
<point key="canvasLocation" x="-82" y="-1306"/>
|
||||
</window>
|
||||
<customObject id="494" userLabel="EmulatorGLView" customClass="EmulatorGLView"/>
|
||||
<customObject id="M8b-ga-iOS" customClass="EmulatorWindowController" colorLabel="IBBuiltInLabel-Blue">
|
||||
@ -472,6 +474,9 @@ CA
|
||||
<buttonCell key="cell" type="push" title="Choose..." bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="nVq-kA-8RS">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<string key="keyEquivalent" base64-UTF8="YES">
|
||||
DQ
|
||||
</string>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="chooseDriveA:" target="FHO-g2-V3A" id="aXp-cp-feH"/>
|
||||
@ -613,19 +618,13 @@ CA
|
||||
<action selector="startupDiskBChoiceChanged:" target="FHO-g2-V3A" id="tQS-5l-DDf"/>
|
||||
</connections>
|
||||
</button>
|
||||
<box verticalHuggingPriority="750" title="Box" boxType="separator" titlePosition="noTitle" id="7ZU-H6-jQn">
|
||||
<box verticalHuggingPriority="750" boxType="separator" id="7ZU-H6-jQn">
|
||||
<rect key="frame" x="12" y="59" width="498" height="5"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
|
||||
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
<font key="titleFont" metaFont="system"/>
|
||||
</box>
|
||||
<box horizontalHuggingPriority="750" title="Box" boxType="separator" titlePosition="noTitle" id="864-Ov-2tE">
|
||||
<box horizontalHuggingPriority="750" boxType="separator" id="864-Ov-2tE">
|
||||
<rect key="frame" x="259" y="70" width="5" height="217"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
|
||||
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
<font key="titleFont" metaFont="system"/>
|
||||
</box>
|
||||
<button verticalHuggingPriority="750" id="tLd-IJ-Kjl">
|
||||
<rect key="frame" x="338" y="13" width="85" height="32"/>
|
||||
@ -633,9 +632,6 @@ CA
|
||||
<buttonCell key="cell" type="push" title="OK" bezelStyle="rounded" alignment="center" borderStyle="border" imageScaling="proportionallyDown" inset="2" id="mSV-MT-MmA">
|
||||
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
<string key="keyEquivalent" base64-UTF8="YES">
|
||||
DQ
|
||||
</string>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="disksOK:" target="FHO-g2-V3A" id="8qD-fL-VNb"/>
|
||||
@ -643,7 +639,7 @@ DQ
|
||||
</button>
|
||||
</subviews>
|
||||
</view>
|
||||
<point key="canvasLocation" x="-139" y="-901"/>
|
||||
<point key="canvasLocation" x="-530" y="-867"/>
|
||||
</window>
|
||||
<customObject id="FHO-g2-V3A" customClass="EmulatorDiskController">
|
||||
<connections>
|
||||
@ -656,6 +652,7 @@ DQ
|
||||
<outlet property="diskInA" destination="cb9-Pc-Ggd" id="chv-2S-Y2R"/>
|
||||
<outlet property="diskInB" destination="5oU-oN-vUH" id="8fb-s5-EKa"/>
|
||||
<outlet property="disksWindow" destination="RAk-at-ZT4" id="4wu-vw-EhL"/>
|
||||
<outlet property="okButton" destination="tLd-IJ-Kjl" id="dvn-gG-jzv"/>
|
||||
<outlet property="startupLoadDiskA" destination="Ur3-rW-YJG" id="re3-gT-qj3"/>
|
||||
<outlet property="startupLoadDiskB" destination="Ceo-uO-cRu" id="V0B-0f-YZu"/>
|
||||
</connections>
|
||||
@ -736,12 +733,9 @@ DQ
|
||||
<action selector="peggedChoiceChanged:" target="mUW-Rh-bL1" id="K2H-Vc-15h"/>
|
||||
</connections>
|
||||
</button>
|
||||
<box verticalHuggingPriority="750" title="Box" boxType="separator" titlePosition="noTitle" id="9U0-v9-wTm">
|
||||
<box verticalHuggingPriority="750" boxType="separator" id="9U0-v9-wTm">
|
||||
<rect key="frame" x="17" y="183" width="508" height="5"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
|
||||
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
<font key="titleFont" metaFont="system"/>
|
||||
</box>
|
||||
<slider verticalHuggingPriority="750" id="y10-Rm-oDB">
|
||||
<rect key="frame" x="15" y="115" width="404" height="27"/>
|
||||
@ -780,7 +774,7 @@ DQ
|
||||
</buttonCell>
|
||||
<cells>
|
||||
<column>
|
||||
<buttonCell type="radio" title="No soundcard" imagePosition="left" alignment="left" enabled="NO" tag="1" inset="2" id="QsT-B1-n2t">
|
||||
<buttonCell type="radio" title="No soundcard" imagePosition="left" alignment="left" enabled="NO" state="on" tag="1" inset="2" id="QsT-B1-n2t">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
@ -809,12 +803,12 @@ DQ
|
||||
<popUpButton verticalHuggingPriority="750" id="1sF-py-jCs">
|
||||
<rect key="frame" x="115" y="271" width="158" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" id="eVj-ax-48A">
|
||||
<popUpButtonCell key="cell" type="push" title="Monochrome" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="PX0-X3-MxY" id="eVj-ax-48A">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="gbp-xU-CmX">
|
||||
<items>
|
||||
<menuItem title="Black/white" id="PX0-X3-MxY">
|
||||
<menuItem title="Monochrome" state="on" id="PX0-X3-MxY">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Color" id="TRN-Jh-rFc">
|
||||
@ -823,6 +817,15 @@ DQ
|
||||
<menuItem title="Interpolated" id="RgR-Oe-oo5">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Color Monitor" id="60c-9H-Yr8">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Monochrome TV" id="lQA-Eh-TKs">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Color TV" id="b41-R4-5E3">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
@ -830,22 +833,8 @@ DQ
|
||||
<action selector="colorChoiceChanged:" target="mUW-Rh-bL1" id="M58-28-Lmr"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<slider verticalHuggingPriority="750" id="9FG-IJ-hYc">
|
||||
<rect key="frame" x="115" y="229" width="404" height="27"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<sliderCell key="cell" enabled="NO" state="on" alignment="left" maxValue="100" doubleValue="50" tickMarkPosition="below" numberOfTickMarks="5" sliderType="linear" id="Cma-o2-8gh"/>
|
||||
</slider>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="RsU-77-Dkx">
|
||||
<rect key="frame" x="15" y="241" width="96" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Graphic Effects :" id="foK-d1-Lrb">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" id="dak-eg-hHn">
|
||||
<rect key="frame" x="15" y="277" width="96" height="17"/>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" misplaced="YES" id="dak-eg-hHn">
|
||||
<rect key="frame" x="15" y="276" width="96" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Color :" id="eHo-1T-edz">
|
||||
<font key="font" metaFont="system"/>
|
||||
@ -853,6 +842,47 @@ DQ
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<textField horizontalHuggingPriority="251" verticalHuggingPriority="750" misplaced="YES" id="rDh-8p-gf0">
|
||||
<rect key="frame" x="15" y="245" width="96" height="17"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<textFieldCell key="cell" scrollable="YES" lineBreakMode="clipping" sendsActionOnEndEditing="YES" alignment="right" title="Monochrome :" id="6zV-cm-vLN">
|
||||
<font key="font" metaFont="system"/>
|
||||
<color key="textColor" name="controlTextColor" catalog="System" colorSpace="catalog"/>
|
||||
<color key="backgroundColor" name="controlColor" catalog="System" colorSpace="catalog"/>
|
||||
</textFieldCell>
|
||||
</textField>
|
||||
<popUpButton verticalHuggingPriority="750" misplaced="YES" id="9bP-5g-S3a">
|
||||
<rect key="frame" x="115" y="240" width="158" height="26"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<popUpButtonCell key="cell" type="push" title="Black/white" bezelStyle="rounded" alignment="left" lineBreakMode="truncatingTail" state="on" borderStyle="borderAndBezel" imageScaling="proportionallyDown" inset="2" selectedItem="7Nj-L6-N5K" id="UkC-75-g1J">
|
||||
<behavior key="behavior" lightByBackground="YES" lightByGray="YES"/>
|
||||
<font key="font" metaFont="menu"/>
|
||||
<menu key="menu" id="8h0-lQ-adO">
|
||||
<items>
|
||||
<menuItem title="Black/white" state="on" id="7Nj-L6-N5K">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem title="Green Screen" id="8Mv-8d-hgV">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</popUpButtonCell>
|
||||
<connections>
|
||||
<action selector="monochromeColorChoiceChanged:" target="mUW-Rh-bL1" id="FIq-tn-pNv"/>
|
||||
</connections>
|
||||
</popUpButton>
|
||||
<button verticalHuggingPriority="750" misplaced="YES" id="0Av-wg-y41">
|
||||
<rect key="frame" x="115" y="219" width="142" height="18"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<buttonCell key="cell" type="check" title="Show half scanlines" bezelStyle="regularSquare" imagePosition="left" inset="2" id="q9I-GX-oEP">
|
||||
<behavior key="behavior" changeContents="YES" doesNotDimImage="YES" lightByContents="YES"/>
|
||||
<font key="font" metaFont="system"/>
|
||||
</buttonCell>
|
||||
<connections>
|
||||
<action selector="scanlinesChoiceChanged:" target="mUW-Rh-bL1" id="7Uf-Tg-ALt"/>
|
||||
</connections>
|
||||
</button>
|
||||
</subviews>
|
||||
</view>
|
||||
</tabViewItem>
|
||||
@ -861,12 +891,9 @@ DQ
|
||||
<rect key="frame" x="10" y="33" width="534" height="298"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<box horizontalHuggingPriority="750" title="Box" boxType="separator" titlePosition="noTitle" id="Fkg-X3-0XG">
|
||||
<box horizontalHuggingPriority="750" boxType="separator" id="Fkg-X3-0XG">
|
||||
<rect key="frame" x="265" y="9" width="5" height="286"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
|
||||
<color key="borderColor" white="0.0" alpha="0.41999999999999998" colorSpace="calibratedWhite"/>
|
||||
<color key="fillColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
<font key="titleFont" metaFont="system"/>
|
||||
</box>
|
||||
<customView id="OWJ-x7-P0q" customClass="EmulatorJoystickCalibrationView">
|
||||
<rect key="frame" x="276" y="39" width="256" height="256"/>
|
||||
@ -1004,7 +1031,7 @@ DQ
|
||||
</tabView>
|
||||
</subviews>
|
||||
</view>
|
||||
<point key="canvasLocation" x="-286" y="-1308"/>
|
||||
<point key="canvasLocation" x="-576" y="-1238"/>
|
||||
</window>
|
||||
<customObject id="mUW-Rh-bL1" customClass="EmulatorPrefsController">
|
||||
<connections>
|
||||
@ -1026,18 +1053,20 @@ DQ
|
||||
<outlet property="joystickStepLabel" destination="ea3-X4-r6a" id="JKX-kB-tcM"/>
|
||||
<outlet property="joystickStepper" destination="BrH-bm-tx3" id="PmM-yE-XNH"/>
|
||||
<outlet property="joystickStepperLabel" destination="e2h-SS-aex" id="I6X-YN-AmA"/>
|
||||
<outlet property="monochromeColorChoice" destination="9bP-5g-S3a" id="dzI-JR-diH"/>
|
||||
<outlet property="scanlinesChoice" destination="0Av-wg-y41" id="U1V-Re-wVs"/>
|
||||
<outlet property="soundCardChoice" destination="3d5-Z5-xDN" id="uHI-Ip-s2E"/>
|
||||
<outlet property="window" destination="Mzv-VG-jce" id="86q-Ys-9Mt"/>
|
||||
</connections>
|
||||
</customObject>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="CPU" width="32" height="32"/>
|
||||
<image name="Disks" width="32" height="32"/>
|
||||
<image name="Fullscreen" width="32" height="32"/>
|
||||
<image name="CPU" width="64" height="64"/>
|
||||
<image name="Disks" width="64" height="64"/>
|
||||
<image name="Fullscreen" width="64" height="64"/>
|
||||
<image name="NSUser" width="32" height="32"/>
|
||||
<image name="Prefs" width="32" height="32"/>
|
||||
<image name="Prefs" width="64" height="64"/>
|
||||
<image name="Reboot" width="32" height="32"/>
|
||||
<image name="Stop" width="32" height="32"/>
|
||||
<image name="Stop" width="64" height="64"/>
|
||||
</resources>
|
||||
</document>
|
||||
|
@ -33,9 +33,21 @@
|
||||
@property (assign) IBOutlet NSButton *chooseDiskB;
|
||||
@property (assign) IBOutlet NSButton *startupLoadDiskA;
|
||||
@property (assign) IBOutlet NSButton *startupLoadDiskB;
|
||||
@property (assign) IBOutlet NSButton *okButton;
|
||||
|
||||
- (void)loadPrefsForDomain:(const char *)domain;
|
||||
|
||||
@end
|
||||
|
||||
static EmulatorDiskController *diskInstance = nil;
|
||||
|
||||
static void prefsChangeCallback(const char *domain)
|
||||
{
|
||||
(void)domain;
|
||||
assert(diskInstance);
|
||||
[diskInstance loadPrefsForDomain:domain];
|
||||
}
|
||||
|
||||
@implementation EmulatorDiskController
|
||||
|
||||
- (void)awakeFromNib
|
||||
@ -43,7 +55,11 @@
|
||||
#if CRASH_APP_ON_LOAD_BECAUSE_YAY_GJ_APPLE
|
||||
glGetError();
|
||||
#endif
|
||||
|
||||
assert(!diskInstance);
|
||||
diskInstance = self;
|
||||
|
||||
prefs_registerListener(PREF_DOMAIN_VM, prefsChangeCallback);
|
||||
|
||||
[self.diskInA setStringValue:NO_DISK_INSERTED];
|
||||
[self.diskAProperties setStringValue:@""];
|
||||
[self.diskInB setStringValue:NO_DISK_INSERTED];
|
||||
@ -52,12 +68,21 @@
|
||||
[self.chooseDiskA setBezelStyle:NSRoundedBezelStyle];
|
||||
[self.startupLoadDiskA setState:NSOffState];
|
||||
[self.startupLoadDiskB setState:NSOffState];
|
||||
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
}
|
||||
|
||||
- (void)loadPrefsForDomain:(const char *)domain
|
||||
{
|
||||
assert(strcmp(domain, PREF_DOMAIN_VM) == 0);
|
||||
(void)domain;
|
||||
|
||||
{
|
||||
NSString *startupDiskA = [defaults stringForKey:kApple2PrefStartupDiskA];
|
||||
BOOL readOnlyA = [defaults boolForKey:kApple2PrefStartupDiskAProtected];
|
||||
NSString *startupDiskA = nil;
|
||||
char *pathA = NULL;
|
||||
startupDiskA = prefs_copyStringValue(PREF_DOMAIN_VM, PREF_DISK_PATH_A, &pathA) ? [NSString stringWithUTF8String:pathA] : nil;
|
||||
FREE(pathA);
|
||||
|
||||
bool bVal = false;
|
||||
BOOL readOnlyA = prefs_parseBoolValue(PREF_DOMAIN_VM, PREF_DISK_PATH_A_RO, &bVal) ? bVal : true;
|
||||
if (startupDiskA)
|
||||
{
|
||||
const char *path = [startupDiskA UTF8String];
|
||||
@ -78,8 +103,13 @@
|
||||
}
|
||||
|
||||
{
|
||||
NSString *startupDiskB = [defaults stringForKey:kApple2PrefStartupDiskB];
|
||||
BOOL readOnlyB = [defaults boolForKey:kApple2PrefStartupDiskBProtected];
|
||||
NSString *startupDiskB = nil;
|
||||
char *pathB = NULL;
|
||||
startupDiskB = prefs_copyStringValue(PREF_DOMAIN_VM, PREF_DISK_PATH_B, &pathB) ? [NSString stringWithUTF8String:pathB] : nil;
|
||||
FREE(pathB);
|
||||
|
||||
bool bVal = false;
|
||||
BOOL readOnlyB = prefs_parseBoolValue(PREF_DOMAIN_VM, PREF_DISK_PATH_B_RO, &bVal) ? bVal : true;
|
||||
if (startupDiskB)
|
||||
{
|
||||
const char *path = [startupDiskB UTF8String];
|
||||
@ -102,34 +132,32 @@
|
||||
|
||||
- (void)_savePrefs
|
||||
{
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
[defaults removeObjectForKey:kApple2PrefStartupDiskA];
|
||||
[defaults removeObjectForKey:kApple2PrefStartupDiskB];
|
||||
[defaults removeObjectForKey:kApple2PrefStartupDiskAProtected];
|
||||
[defaults removeObjectForKey:kApple2PrefStartupDiskBProtected];
|
||||
|
||||
if ([self.startupLoadDiskA state] == NSOnState)
|
||||
if (([self.startupLoadDiskA state] == NSOnState) && (disk6.disk[0].fd >= 0))
|
||||
{
|
||||
if (disk6.disk[0].fd >= 0)
|
||||
{
|
||||
NSString *diskA = [NSString stringWithUTF8String:disk6.disk[0].file_name];
|
||||
[defaults setObject:diskA forKey:kApple2PrefStartupDiskA];
|
||||
NSButtonCell *readOnlyChoice = (NSButtonCell *)[[[self diskAProtection] cells] firstObject];
|
||||
[defaults setBool:([readOnlyChoice state] == NSOnState) forKey:kApple2PrefStartupDiskAProtected];
|
||||
}
|
||||
prefs_setStringValue(PREF_DOMAIN_VM, PREF_DISK_PATH_A, disk6.disk[0].file_name);
|
||||
NSButtonCell *readOnlyChoice = (NSButtonCell *)[[[self diskAProtection] cells] firstObject];
|
||||
prefs_setBoolValue(PREF_DOMAIN_VM, PREF_DISK_PATH_A_RO, ([readOnlyChoice state] == NSOnState));
|
||||
}
|
||||
else
|
||||
{
|
||||
prefs_setStringValue(PREF_DOMAIN_VM, PREF_DISK_PATH_A, "");
|
||||
prefs_setBoolValue(PREF_DOMAIN_VM, PREF_DISK_PATH_A_RO, true);
|
||||
}
|
||||
|
||||
if ([self.startupLoadDiskB state] == NSOnState)
|
||||
if (([self.startupLoadDiskB state] == NSOnState) && (disk6.disk[1].fd >= 0))
|
||||
{
|
||||
if (disk6.disk[1].fd >= 0)
|
||||
{
|
||||
NSString *diskB = [NSString stringWithUTF8String:disk6.disk[1].file_name];
|
||||
[defaults setObject:diskB forKey:kApple2PrefStartupDiskB];
|
||||
NSButtonCell *readOnlyChoice = (NSButtonCell *)[[[self diskBProtection] cells] firstObject];
|
||||
[defaults setBool:([readOnlyChoice state] == NSOnState) forKey:kApple2PrefStartupDiskBProtected];
|
||||
}
|
||||
prefs_setStringValue(PREF_DOMAIN_VM, PREF_DISK_PATH_B, disk6.disk[1].file_name);
|
||||
NSButtonCell *readOnlyChoice = (NSButtonCell *)[[[self diskBProtection] cells] firstObject];
|
||||
prefs_setBoolValue(PREF_DOMAIN_VM, PREF_DISK_PATH_B_RO, ([readOnlyChoice state] == NSOnState) );
|
||||
}
|
||||
else
|
||||
{
|
||||
prefs_setStringValue(PREF_DOMAIN_VM, PREF_DISK_PATH_B, "");
|
||||
prefs_setBoolValue(PREF_DOMAIN_VM, PREF_DISK_PATH_B_RO, true);
|
||||
}
|
||||
|
||||
prefs_sync(PREF_DOMAIN_VM);
|
||||
prefs_save();
|
||||
}
|
||||
|
||||
- (void)_protectionChangedForDrive:(int)drive
|
||||
@ -185,12 +213,21 @@
|
||||
}
|
||||
path = [NSString stringWithUTF8String:disk6.disk[drive].file_name];
|
||||
NSString *imageName = [[path pathComponents] lastObject];
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
|
||||
|
||||
if (drive == 0)
|
||||
{
|
||||
[[self diskInA] setStringValue:imageName];
|
||||
if ([[defaults stringForKey:kApple2PrefStartupDiskA] isEqualToString:path])
|
||||
|
||||
bool isStartupDiskA = false;
|
||||
{
|
||||
char *pathA = NULL;
|
||||
if (prefs_copyStringValue(PREF_DOMAIN_VM, PREF_DISK_PATH_A, &pathA)) {
|
||||
isStartupDiskA = (strcmp(pathA, disk6.disk[drive].file_name) == 0);
|
||||
}
|
||||
FREE(pathA);
|
||||
}
|
||||
|
||||
if (isStartupDiskA)
|
||||
{
|
||||
[self.startupLoadDiskA setState:NSOnState];
|
||||
//[self.diskAProtection setState:(readOnly ? NSOnState : NSOffState) atRow:0 column:0];
|
||||
@ -200,7 +237,17 @@
|
||||
else
|
||||
{
|
||||
[[self diskInB] setStringValue:imageName];
|
||||
if ([[defaults stringForKey:kApple2PrefStartupDiskB] isEqualToString:path])
|
||||
|
||||
bool isStartupDiskB = false;
|
||||
{
|
||||
char *pathB = NULL;
|
||||
if (prefs_copyStringValue(PREF_DOMAIN_VM, PREF_DISK_PATH_B, &pathB)) {
|
||||
isStartupDiskB = (strcmp(pathB, disk6.disk[drive].file_name) == 0);
|
||||
}
|
||||
FREE(pathB);
|
||||
}
|
||||
|
||||
if (isStartupDiskB)
|
||||
{
|
||||
[self.startupLoadDiskB setState:NSOnState];
|
||||
//[self.diskBProtection setState:(readOnly ? NSOnState : NSOffState) atRow:0 column:0];
|
||||
@ -304,6 +351,9 @@
|
||||
return;
|
||||
}
|
||||
|
||||
[self.chooseDiskA setKeyEquivalent:@""];
|
||||
[self.okButton setKeyEquivalent:@"\r"];
|
||||
|
||||
[(drive == 0) ? self.startupLoadDiskA : self.startupLoadDiskB setState:NSOffState];
|
||||
[self _insertDisketteInDrive:drive path:path type:extension readOnly:readOnly];
|
||||
}
|
||||
@ -334,6 +384,9 @@
|
||||
|
||||
- (IBAction)disksOK:(id)sender
|
||||
{
|
||||
[self.chooseDiskA setKeyEquivalent:@"\r"];
|
||||
[self.okButton setKeyEquivalent:@""];
|
||||
|
||||
[[self disksWindow] close];
|
||||
}
|
||||
|
||||
|
@ -11,11 +11,6 @@
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
#define kApple2PrefStartupDiskA @"kApple2PrefStartupDiskA"
|
||||
#define kApple2PrefStartupDiskAProtected @"kApple2PrefStartupDiskAProtected"
|
||||
#define kApple2PrefStartupDiskB @"kApple2PrefStartupDiskB"
|
||||
#define kApple2PrefStartupDiskBProtected @"kApple2PrefStartupDiskBProtected"
|
||||
|
||||
@interface EmulatorPrefsController : NSWindowController
|
||||
|
||||
@end
|
||||
|
@ -15,18 +15,6 @@
|
||||
#import "EmulatorWindowController.h"
|
||||
#import "common.h"
|
||||
|
||||
#define kApple2SavedPrefs @"kApple2SavedPrefs"
|
||||
#define kApple2CPUSpeed @"kApple2CPUSpeed"
|
||||
#define kApple2CPUSpeedIsMax @"kApple2CPUSpeedIsMax"
|
||||
#define kApple2AltSpeed @"kApple2AltSpeed"
|
||||
#define kApple2AltSpeedIsMax @"kApple2AltSpeedIsMax"
|
||||
#define kApple2SoundcardConfig @"kApple2SoundcardConfig"
|
||||
#define kApple2ColorConfig @"kApple2ColorConfig"
|
||||
#define kApple2JoystickConfig @"kApple2JoystickConfig"
|
||||
#define kApple2JoystickAutoRecenter @"kApple2JoystickAutoRecenter"
|
||||
#define kApple2JoystickClipToRadius @"kApple2JoystickClipToRadius"
|
||||
#define kApple2JoystickStep @"kApple2JoystickStep"
|
||||
|
||||
@interface EmulatorPrefsController ()
|
||||
|
||||
@property (assign) IBOutlet NSSlider *cpuSlider;
|
||||
@ -39,6 +27,8 @@
|
||||
@property (assign) IBOutlet NSMatrix *soundCardChoice;
|
||||
|
||||
@property (assign) IBOutlet NSPopUpButton *colorChoice;
|
||||
@property (assign) IBOutlet NSPopUpButton *monochromeColorChoice;
|
||||
@property (assign) IBOutlet NSButton *scanlinesChoice;
|
||||
|
||||
@property (assign) IBOutlet NSPopUpButton *joystickChoice;
|
||||
@property (assign) IBOutlet NSButton *joystickRecenter;
|
||||
@ -53,34 +43,44 @@
|
||||
@property (assign) IBOutlet NSTextField *button1Pressed;
|
||||
@property (assign) IBOutlet EmulatorJoystickCalibrationView *joystickCalibrationView;
|
||||
|
||||
- (void)loadPrefsForDomain:(const char *)domain;
|
||||
|
||||
@end
|
||||
|
||||
static EmulatorPrefsController *prefsInstance = nil;
|
||||
|
||||
static void prefsChangeCallback(const char *domain)
|
||||
{
|
||||
(void)domain;
|
||||
assert(prefsInstance);
|
||||
[prefsInstance loadPrefsForDomain:domain];
|
||||
}
|
||||
|
||||
@implementation EmulatorPrefsController
|
||||
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
BOOL firstTime = ![defaults boolForKey:kApple2SavedPrefs];
|
||||
if (firstTime)
|
||||
{
|
||||
[defaults setBool:YES forKey:kApple2SavedPrefs];
|
||||
[defaults setDouble:1.0 forKey:kApple2CPUSpeed];
|
||||
[defaults setDouble:CPU_SCALE_SLOWEST forKey:kApple2AltSpeed];
|
||||
[defaults setBool:NO forKey:kApple2CPUSpeedIsMax];
|
||||
[defaults setBool:NO forKey:kApple2AltSpeedIsMax];
|
||||
[defaults setInteger:COLOR_MODE_INTERP forKey:kApple2ColorConfig];
|
||||
[defaults setInteger:JOY_KPAD forKey:kApple2JoystickConfig];
|
||||
[defaults setBool:YES forKey:kApple2JoystickAutoRecenter];
|
||||
[defaults removeObjectForKey:kApple2PrefStartupDiskA];
|
||||
[defaults removeObjectForKey:kApple2PrefStartupDiskB];
|
||||
}
|
||||
|
||||
cpu_scale_factor = [defaults doubleForKey:kApple2CPUSpeed];
|
||||
assert(!prefsInstance);
|
||||
prefsInstance = self;
|
||||
|
||||
prefs_registerListener(PREF_DOMAIN_AUDIO, prefsChangeCallback);
|
||||
prefs_registerListener(PREF_DOMAIN_INTERFACE, prefsChangeCallback);
|
||||
prefs_registerListener(PREF_DOMAIN_JOYSTICK, prefsChangeCallback);
|
||||
prefs_registerListener(PREF_DOMAIN_KEYBOARD, prefsChangeCallback);
|
||||
//prefs_registerListener(PREF_DOMAIN_TOUCHSCREEN, prefsChangeCallback);
|
||||
prefs_registerListener(PREF_DOMAIN_VIDEO, prefsChangeCallback);
|
||||
prefs_registerListener(PREF_DOMAIN_VM, prefsChangeCallback);
|
||||
|
||||
[self _setupJoystickUI];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(drawJoystickCalibration:) name:(NSString *)kDrawTimerNotification object:nil];
|
||||
}
|
||||
|
||||
- (void)loadPrefsForDomain:(const char *)domain
|
||||
{
|
||||
[self.cpuSlider setDoubleValue:cpu_scale_factor];
|
||||
[self.cpuSliderLabel setStringValue:[NSString stringWithFormat:@"%.0f%%", cpu_scale_factor*100]];
|
||||
if ([defaults boolForKey:kApple2CPUSpeedIsMax])
|
||||
if (cpu_scale_factor == CPU_SCALE_FASTEST)
|
||||
{
|
||||
cpu_scale_factor = CPU_SCALE_FASTEST;
|
||||
[self.cpuMaxChoice setState:NSOnState];
|
||||
[self.cpuSlider setEnabled:NO];
|
||||
}
|
||||
@ -90,12 +90,10 @@
|
||||
[self.cpuSlider setEnabled:YES];
|
||||
}
|
||||
|
||||
cpu_altscale_factor = [defaults doubleForKey:kApple2AltSpeed];
|
||||
[self.altSlider setDoubleValue:cpu_altscale_factor];
|
||||
[self.altSliderLabel setStringValue:[NSString stringWithFormat:@"%.0f%%", cpu_altscale_factor*100]];
|
||||
if ([defaults boolForKey:kApple2AltSpeedIsMax])
|
||||
if (cpu_altscale_factor == CPU_SCALE_FASTEST)
|
||||
{
|
||||
cpu_altscale_factor = CPU_SCALE_FASTEST;
|
||||
[self.altMaxChoice setState:NSOnState];
|
||||
[self.altSlider setEnabled:NO];
|
||||
}
|
||||
@ -108,46 +106,21 @@
|
||||
#warning TODO : actually implement sound card choices
|
||||
[self.soundCardChoice deselectAllCells];
|
||||
[self.soundCardChoice selectCellAtRow:1 column:0];
|
||||
|
||||
NSInteger mode = [defaults integerForKey:kApple2ColorConfig];
|
||||
if (! ((mode >= COLOR_MODE_BW) && (mode < NUM_COLOROPTS)) )
|
||||
{
|
||||
mode = COLOR_MODE_BW;
|
||||
}
|
||||
[self.colorChoice selectItemAtIndex:mode];
|
||||
prefs_setLongValue(PREF_DOMAIN_VIDEO, PREF_COLOR_MODE, (color_mode_t)mode);
|
||||
prefs_sync(PREF_DOMAIN_VIDEO);
|
||||
|
||||
mode = [defaults integerForKey:kApple2JoystickConfig];
|
||||
if (! ((mode >= JOY_PCJOY) && (mode < NUM_JOYOPTS)) )
|
||||
{
|
||||
mode = JOY_PCJOY;
|
||||
}
|
||||
joy_mode = (joystick_mode_t)mode;
|
||||
[self.joystickChoice selectItemAtIndex:mode];
|
||||
long lVal = 0;
|
||||
NSInteger mode = prefs_parseLongValue(domain, PREF_COLOR_MODE, &lVal, /*base:*/10) ? getColorMode(lVal) : COLOR_MODE_DEFAULT;
|
||||
[self.colorChoice selectItemAtIndex:mode];
|
||||
|
||||
[self.joystickChoice selectItemAtIndex:(NSInteger)joy_mode];
|
||||
|
||||
#ifdef KEYPAD_JOYSTICK
|
||||
bool autoRecenter = [defaults integerForKey:kApple2JoystickAutoRecenter];
|
||||
[self.joystickRecenter setState:autoRecenter ? NSOnState : NSOffState];
|
||||
prefs_setBoolValue(PREF_DOMAIN_JOYSTICK, PREF_JOYSTICK_KPAD_AUTO_RECENTER, autoRecenter);
|
||||
|
||||
long joyStep = [defaults integerForKey:kApple2JoystickStep];
|
||||
if (!joyStep)
|
||||
{
|
||||
joyStep = 1;
|
||||
}
|
||||
[self.joystickStepLabel setIntegerValue:joyStep];
|
||||
[self.joystickStepper setIntegerValue:joyStep];
|
||||
prefs_setLongValue(PREF_DOMAIN_JOYSTICK, PREF_JOYSTICK_KPAD_STEP, joyStep);
|
||||
|
||||
prefs_sync(PREF_DOMAIN_JOYSTICK);
|
||||
[self.joystickRecenter setState:joy_auto_recenter ? NSOnState : NSOffState];
|
||||
|
||||
[self.joystickStepLabel setIntegerValue:joy_step];
|
||||
[self.joystickStepper setIntegerValue:joy_step];
|
||||
#endif
|
||||
|
||||
joy_clip_to_radius = [defaults boolForKey:kApple2JoystickClipToRadius];
|
||||
[self.joystickClipToRadius setState:joy_clip_to_radius ? NSOnState : NSOffState];
|
||||
|
||||
[self _setupJoystickUI];
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(drawJoystickCalibration:) name:(NSString *)kDrawTimerNotification object:nil];
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
@ -156,49 +129,23 @@
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)_savePrefs
|
||||
{
|
||||
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
|
||||
[defaults setBool:YES forKey:kApple2SavedPrefs];
|
||||
[defaults setDouble:cpu_scale_factor forKey:kApple2CPUSpeed];
|
||||
[defaults setDouble:cpu_altscale_factor forKey:kApple2AltSpeed];
|
||||
[defaults setBool:([self.cpuMaxChoice state] == NSOnState) forKey:kApple2CPUSpeedIsMax];
|
||||
[defaults setBool:([self.altMaxChoice state] == NSOnState) forKey:kApple2AltSpeedIsMax];
|
||||
|
||||
long lVal = 0;
|
||||
color_mode_t mode = prefs_parseLongValue(PREF_DOMAIN_VIDEO, PREF_COLOR_MODE, &lVal, /*base:*/10) ? (color_mode_t)lVal : COLOR_MODE_INTERP;
|
||||
[defaults setInteger:mode forKey:kApple2ColorConfig];
|
||||
[defaults setInteger:joy_mode forKey:kApple2JoystickConfig];
|
||||
|
||||
long joyStep = prefs_parseLongValue(PREF_DOMAIN_JOYSTICK, PREF_JOYSTICK_KPAD_STEP, &lVal, /*base:*/10) ? lVal : 1;
|
||||
[defaults setInteger:joyStep forKey:kApple2JoystickStep];
|
||||
|
||||
bool bVal = false;
|
||||
bool autoRecenter = prefs_parseBoolValue(PREF_DOMAIN_JOYSTICK, PREF_JOYSTICK_KPAD_AUTO_RECENTER, &bVal) ? bVal : true;
|
||||
[defaults setBool:autoRecenter forKey:kApple2JoystickAutoRecenter];
|
||||
[defaults setBool:joy_clip_to_radius forKey:kApple2JoystickClipToRadius];
|
||||
|
||||
prefs_sync(PREF_DOMAIN_JOYSTICK);
|
||||
}
|
||||
|
||||
- (IBAction)sliderDidMove:(id)sender
|
||||
{
|
||||
NSSlider *slider = (NSSlider *)sender;
|
||||
double value = [slider doubleValue];
|
||||
if (slider == self.cpuSlider)
|
||||
{
|
||||
cpu_scale_factor = value;
|
||||
prefs_setFloatValue(PREF_DOMAIN_VM, PREF_CPU_SCALE, value);
|
||||
[self.cpuSliderLabel setStringValue:[NSString stringWithFormat:@"%.0f%%", value*100]];
|
||||
}
|
||||
else
|
||||
{
|
||||
cpu_altscale_factor = value;
|
||||
prefs_setFloatValue(PREF_DOMAIN_VM, PREF_CPU_SCALE_ALT, value);
|
||||
[self.altSliderLabel setStringValue:[NSString stringWithFormat:@"%.0f%%", value*100]];
|
||||
}
|
||||
|
||||
timing_initialize();
|
||||
|
||||
[self _savePrefs];
|
||||
prefs_sync(PREF_DOMAIN_VM);
|
||||
prefs_save();
|
||||
}
|
||||
|
||||
- (IBAction)peggedChoiceChanged:(id)sender
|
||||
@ -207,32 +154,43 @@
|
||||
if (maxButton == self.cpuMaxChoice)
|
||||
{
|
||||
[self.cpuSlider setEnabled:([maxButton state] != NSOnState)];
|
||||
cpu_scale_factor = ([maxButton state] == NSOnState) ? CPU_SCALE_FASTEST : [self.cpuSlider doubleValue];
|
||||
double value = ([maxButton state] == NSOnState) ? CPU_SCALE_FASTEST : [self.cpuSlider doubleValue];
|
||||
prefs_setFloatValue(PREF_DOMAIN_VM, PREF_CPU_SCALE, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
[self.altSlider setEnabled:([maxButton state] != NSOnState)];
|
||||
cpu_altscale_factor = ([maxButton state] == NSOnState) ? CPU_SCALE_FASTEST : [self.altSlider doubleValue];
|
||||
double value = ([maxButton state] == NSOnState) ? CPU_SCALE_FASTEST : [self.altSlider doubleValue];
|
||||
prefs_setFloatValue(PREF_DOMAIN_VM, PREF_CPU_SCALE_ALT, value);
|
||||
}
|
||||
|
||||
timing_initialize();
|
||||
|
||||
[self _savePrefs];
|
||||
prefs_sync(PREF_DOMAIN_VM);
|
||||
prefs_save();
|
||||
}
|
||||
|
||||
- (IBAction)colorChoiceChanged:(id)sender
|
||||
{
|
||||
NSInteger mode = [self.colorChoice indexOfSelectedItem];
|
||||
if (! ((mode >= COLOR_MODE_BW) && (mode < NUM_COLOROPTS)) )
|
||||
{
|
||||
mode = COLOR_MODE_BW;
|
||||
}
|
||||
mode = getColorMode(mode);
|
||||
prefs_setLongValue(PREF_DOMAIN_VIDEO, PREF_COLOR_MODE, mode);
|
||||
prefs_sync(PREF_DOMAIN_VIDEO);
|
||||
[self _savePrefs];
|
||||
|
||||
#warning HACK TODO FIXME need to refactor video resetting procedure
|
||||
display_reset();
|
||||
prefs_save();
|
||||
}
|
||||
|
||||
- (IBAction)monochromeColorChoiceChanged:(id)sender {
|
||||
NSInteger mode = [self.monochromeColorChoice indexOfSelectedItem];
|
||||
mode = getMonoMode(mode);
|
||||
prefs_setLongValue(PREF_DOMAIN_VIDEO, PREF_MONO_MODE, mode);
|
||||
prefs_sync(PREF_DOMAIN_VIDEO);
|
||||
prefs_save();
|
||||
}
|
||||
|
||||
- (IBAction)scanlinesChoiceChanged:(id)sender
|
||||
{
|
||||
NSControlStateValue state = [self.scanlinesChoice state];
|
||||
prefs_setBoolValue(PREF_DOMAIN_VIDEO, PREF_SHOW_HALF_SCANLINES, state == NSControlStateValueOn);
|
||||
prefs_sync(PREF_DOMAIN_VIDEO);
|
||||
prefs_save();
|
||||
}
|
||||
|
||||
- (IBAction)soundCardChoiceChanged:(id)sender
|
||||
@ -257,34 +215,35 @@
|
||||
- (IBAction)joystickChoiceChanged:(id)sender
|
||||
{
|
||||
NSInteger mode = [self.joystickChoice indexOfSelectedItem];
|
||||
if (! ((mode >= JOY_PCJOY) && (mode < NUM_JOYOPTS)) )
|
||||
{
|
||||
mode = JOY_PCJOY;
|
||||
}
|
||||
joy_mode = (joystick_mode_t)mode;
|
||||
[self _setupJoystickUI];
|
||||
[self _savePrefs];
|
||||
mode = getJoyMode(mode);
|
||||
prefs_setLongValue(PREF_DOMAIN_JOYSTICK, PREF_JOYSTICK_MODE, mode);
|
||||
prefs_sync(PREF_DOMAIN_JOYSTICK);
|
||||
prefs_save();
|
||||
}
|
||||
|
||||
- (IBAction)autoRecenterChoiceChanged:(id)sender
|
||||
{
|
||||
bool autoRecenter = ([self.joystickRecenter state] == NSOnState);
|
||||
prefs_setBoolValue(PREF_DOMAIN_JOYSTICK, PREF_JOYSTICK_KPAD_AUTO_RECENTER, autoRecenter);
|
||||
[self _savePrefs];
|
||||
prefs_sync(PREF_DOMAIN_JOYSTICK);
|
||||
prefs_save();
|
||||
}
|
||||
|
||||
- (IBAction)clipToRadiusChoiceChanged:(id)sender
|
||||
{
|
||||
joy_clip_to_radius = ([self.joystickClipToRadius state] == NSOnState);
|
||||
[self _savePrefs];
|
||||
bool clipToRadius = ([self.joystickClipToRadius state] == NSOnState);
|
||||
prefs_setBoolValue(PREF_DOMAIN_JOYSTICK, PREF_JOYSTICK_CLIP_TO_RADIUS, clipToRadius);
|
||||
prefs_sync(PREF_DOMAIN_JOYSTICK);
|
||||
prefs_save();
|
||||
}
|
||||
|
||||
- (IBAction)stepValueChanged:(id)sender
|
||||
{
|
||||
long joyStep = [self.joystickStepper intValue];
|
||||
[self.joystickStepLabel setIntegerValue:joyStep];
|
||||
prefs_setLongValue(PREF_DOMAIN_JOYSTICK, PREF_JOYSTICK_KPAD_AUTO_RECENTER, joyStep);
|
||||
[self _savePrefs];
|
||||
prefs_setLongValue(PREF_DOMAIN_JOYSTICK, PREF_JOYSTICK_KPAD_STEP, joyStep);
|
||||
prefs_sync(PREF_DOMAIN_JOYSTICK);
|
||||
prefs_save();
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
1492
src/display.c
1492
src/display.c
File diff suppressed because it is too large
Load Diff
204
src/display.h
204
src/display.h
@ -12,16 +12,27 @@
|
||||
#ifndef _DISPLAY_H_
|
||||
#define _DISPLAY_H_
|
||||
|
||||
#include "common.h"
|
||||
#if USE_RGBA4444
|
||||
#error HACK FIXME TODO : 2018/09/23 currently untested
|
||||
# define PIXEL_TYPE uint16_t
|
||||
# define MAX_SATURATION 0xf
|
||||
# define SHIFT_R 12
|
||||
# define SHIFT_G 8
|
||||
# define SHIFT_B 4
|
||||
# define SHIFT_A 0
|
||||
# define RGB_MASK 0xFFF0
|
||||
#else
|
||||
// assuming RGBA8888 ...
|
||||
# define PIXEL_TYPE uint32_t
|
||||
# define MAX_SATURATION 0xff
|
||||
# define SHIFT_R 0
|
||||
# define SHIFT_G 8
|
||||
# define SHIFT_B 16
|
||||
# define SHIFT_A 24
|
||||
# define RGB_MASK 0xFFFFFF
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Color structure
|
||||
*/
|
||||
typedef struct A2Color_s {
|
||||
uint8_t red;
|
||||
uint8_t green;
|
||||
uint8_t blue;
|
||||
} A2Color_s;
|
||||
#define PIXEL_STRIDE (sizeof(PIXEL_TYPE))
|
||||
|
||||
/*
|
||||
* Scanline data
|
||||
@ -34,38 +45,102 @@ typedef struct scan_data_t {
|
||||
unsigned int scanend; // 0 >= x < 80
|
||||
} scan_data_t;
|
||||
|
||||
#define IDX_BLACK 0x00
|
||||
#define IDX_MAGENTA 0x10
|
||||
#define IDX_DARKBLUE 0x20
|
||||
#define IDX_PURPLE 0x30
|
||||
#define IDX_DARKGREEN 0x40
|
||||
#define IDX_DARKGREY 0x50
|
||||
#define IDX_MEDBLUE 0x60
|
||||
#define IDX_LIGHTBLUE 0x70
|
||||
#define IDX_BROWN 0x80
|
||||
#define IDX_ORANGE 0x90
|
||||
#define IDX_LIGHTGREY 0xa0
|
||||
#define IDX_PINK 0xb0
|
||||
#define IDX_GREEN 0xc0
|
||||
#define IDX_YELLOW 0xd0
|
||||
#define IDX_AQUA 0xe0
|
||||
#define IDX_WHITE 0xf0
|
||||
#define IDX_BLACK 0x00 // 0000
|
||||
#define IDX_MAGENTA 0x01 // 0001
|
||||
#define IDX_DARKBLUE 0x02 // 0010
|
||||
#define IDX_PURPLE 0x03 // 0011 - HIRES40
|
||||
#define IDX_DARKGREEN 0x04 // 0100
|
||||
#define IDX_DARKGREY 0x05 // 0101
|
||||
#define IDX_MEDBLUE 0x06 // 0110 - HIRES40
|
||||
#define IDX_LIGHTBLUE 0x07 // 0111
|
||||
#define IDX_BROWN 0x08 // 1000
|
||||
#define IDX_ORANGE 0x09 // 1001 - HIRES40
|
||||
#define IDX_LIGHTGREY 0x0a // 1010
|
||||
#define IDX_PINK 0x0b // 1011
|
||||
#define IDX_GREEN 0x0c // 1100 - HIRES40
|
||||
#define IDX_YELLOW 0x0d // 1101
|
||||
#define IDX_AQUA 0x0e // 1110
|
||||
#define IDX_WHITE 0x0f // 1111
|
||||
|
||||
/*
|
||||
* Reference to the internal 8bit-indexed color format
|
||||
*/
|
||||
extern A2Color_s colormap[];
|
||||
// Colors duplicated and muted at this offset
|
||||
#define IDX_LUMINANCE_HALF 0x40
|
||||
|
||||
// Interface colors
|
||||
#define IDX_ICOLOR_R 0x21
|
||||
#define IDX_ICOLOR_G 0x22
|
||||
#define IDX_ICOLOR_B 0x23
|
||||
|
||||
typedef enum interface_colorscheme_t {
|
||||
GREEN_ON_BLACK = 0,
|
||||
GREEN_ON_BLUE,
|
||||
RED_ON_BLACK,
|
||||
BLUE_ON_BLACK,
|
||||
WHITE_ON_BLACK,
|
||||
|
||||
// WARNING : changing here requires updating display.c ncvideo.c
|
||||
|
||||
BLACK_ON_RED,
|
||||
|
||||
// 16 COLORS -- ncvideo.c
|
||||
BLACK_ON_BLACK,
|
||||
BLACK_ON_MAGENTA,
|
||||
BLACK_ON_DARKBLUE,
|
||||
BLACK_ON_PURPLE,
|
||||
BLACK_ON_DARKGREEN,
|
||||
BLACK_ON_DARKGREY,
|
||||
BLACK_ON_MEDBLUE,
|
||||
BLACK_ON_LIGHTBLUE,
|
||||
BLACK_ON_BROWN,
|
||||
BLACK_ON_ORANGE,
|
||||
BLACK_ON_LIGHTGREY,
|
||||
BLACK_ON_PINK,
|
||||
BLACK_ON_GREEN,
|
||||
BLACK_ON_YELLOW,
|
||||
BLACK_ON_AQUA,
|
||||
BLACK_ON_WHITE,
|
||||
|
||||
NUM_INTERFACE_COLORSCHEMES,
|
||||
COLOR16 = 0x80,
|
||||
INVALID_COLORSCHEME = 0xFF,
|
||||
} interface_colorscheme_t;
|
||||
|
||||
/*
|
||||
* Color options
|
||||
*/
|
||||
typedef enum color_mode_t {
|
||||
COLOR_MODE_BW = 0,
|
||||
// original modes ...
|
||||
COLOR_MODE_MONO = 0,
|
||||
COLOR_MODE_COLOR,
|
||||
COLOR_MODE_INTERP,
|
||||
NUM_COLOROPTS
|
||||
// NTSC color modes ...
|
||||
COLOR_MODE_COLOR_MONITOR,
|
||||
COLOR_MODE_MONO_TV,
|
||||
COLOR_MODE_COLOR_TV,
|
||||
NUM_COLOROPTS,
|
||||
} color_mode_t;
|
||||
|
||||
#define COLOR_MODE_DEFAULT COLOR_MODE_COLOR_TV
|
||||
static inline color_mode_t getColorMode(long lVal) {
|
||||
if (lVal < 0 || lVal >= NUM_COLOROPTS) {
|
||||
lVal = COLOR_MODE_DEFAULT;
|
||||
}
|
||||
return (color_mode_t)lVal;
|
||||
}
|
||||
|
||||
typedef enum mono_mode_t {
|
||||
MONO_MODE_BW = 0,
|
||||
MONO_MODE_GREEN,
|
||||
NUM_MONOOPTS,
|
||||
} mono_mode_t;
|
||||
|
||||
#define MONO_MODE_DEFAULT MONO_MODE_BW
|
||||
static inline mono_mode_t getMonoMode(long lVal) {
|
||||
if (lVal < 0 || lVal >= NUM_MONOOPTS) {
|
||||
lVal = MONO_MODE_DEFAULT;
|
||||
}
|
||||
return (mono_mode_t)lVal;
|
||||
}
|
||||
|
||||
/*
|
||||
* Font mode
|
||||
*/
|
||||
@ -87,17 +162,6 @@ typedef enum drawpage_mode_t {
|
||||
NUM_DRAWPAGE_MODES,
|
||||
} drawpage_mode_t;
|
||||
|
||||
/*
|
||||
* Setup the display. This may be called multiple times in a run, and is
|
||||
* used when graphics parameters may have changed.
|
||||
*
|
||||
* This function is responsible for inserting any needed video-specific hooks
|
||||
* into the 6502 memory indirection table. It should *not* hook the
|
||||
* soft-switches.
|
||||
*
|
||||
*/
|
||||
void display_reset(void);
|
||||
|
||||
/*
|
||||
* Set the font used by the display. QTY characters are loaded starting
|
||||
* with FIRST, from DATA. DATA contains 8 bytes for each character, each
|
||||
@ -127,7 +191,6 @@ void display_flashText(void);
|
||||
#if INTERFACE_CLASSIC
|
||||
/*
|
||||
* Plot character into interface framebuffer.
|
||||
* - Pixels in the framebuffer are 8bit indexed color into the colormap array
|
||||
* - This should only be called from video backends/interface
|
||||
*/
|
||||
void display_plotChar(const uint8_t col, const uint8_t row, const interface_colorscheme_t cs, const uint8_t c);
|
||||
@ -143,17 +206,21 @@ void display_plotLine(const uint8_t col, const uint8_t row, const interface_colo
|
||||
* Plot multi-line message into given framebuffer (not the interface framebuffer).
|
||||
* - See display_plotChar() ...
|
||||
*/
|
||||
void display_plotMessage(uint8_t *fb, const interface_colorscheme_t cs, const char *message, const uint8_t message_cols, const uint8_t message_rows);
|
||||
void display_plotMessage(PIXEL_TYPE *fb, const interface_colorscheme_t cs, const char *message, const uint8_t message_cols, const uint8_t message_rows);
|
||||
|
||||
/*
|
||||
* Get video line offset for TEXT mode row
|
||||
*/
|
||||
uint16_t display_getVideoLineOffset(uint8_t txtRow);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// video generation
|
||||
|
||||
/*
|
||||
* Called by video backend to get the current complete staging framebuffer.
|
||||
* - Framebuffer is exactly SCANWIDTH*SCANHEIGHT*sizeof(uint8_t) size
|
||||
* - Pixels in the framebuffer are 8bit indexed color into the colormap array
|
||||
* - Framebuffer is exactly SCANWIDTH*SCANHEIGHT*sizeof(PIXEL_TYPE)
|
||||
*/
|
||||
uint8_t *display_getCurrentFramebuffer(void) CALL_ON_UI_THREAD;
|
||||
PIXEL_TYPE *display_getCurrentFramebuffer(void) CALL_ON_UI_THREAD;
|
||||
|
||||
/*
|
||||
* Handler for toggling text flashing
|
||||
@ -193,10 +260,11 @@ uint8_t *display_waitForNextCompleteFramebuffer(void);
|
||||
#define SCANHEIGHT (TEXT_ROWS * FONT_HEIGHT_PIXELS) // 384
|
||||
|
||||
// Extra bytes on each side of internal framebuffers for color interpolation hack
|
||||
#define _INTERPOLATED_PIXEL_ADJUSTMENT_PRE 4
|
||||
#define _INTERPOLATED_PIXEL_ADJUSTMENT_POST 4
|
||||
#define _FB_OFF 4
|
||||
#define _INTERPOLATED_PIXEL_ADJUSTMENT_PRE _FB_OFF
|
||||
#define _INTERPOLATED_PIXEL_ADJUSTMENT_POST _FB_OFF
|
||||
#define INTERPOLATED_PIXEL_ADJUSTMENT (_INTERPOLATED_PIXEL_ADJUSTMENT_PRE+_INTERPOLATED_PIXEL_ADJUSTMENT_POST)
|
||||
#define SCANWIDTH (_SCANWIDTH+INTERPOLATED_PIXEL_ADJUSTMENT)
|
||||
#define SCANWIDTH (_SCANWIDTH+INTERPOLATED_PIXEL_ADJUSTMENT) // 568
|
||||
|
||||
#define FONT_GLYPH_X (7+/*unused*/1) // generated font.c uses a single byte (8bits) per font glyph line
|
||||
#define FONT_GLYPH_Y (FONT_HEIGHT_PIXELS>>1) // ... 8 bytes total for whole glyph
|
||||
@ -249,42 +317,6 @@ uint8_t *display_waitForNextCompleteFramebuffer(void);
|
||||
#define ICONTEXT_LEFT_TAB (ICONTEXT_KBD_BEGIN+0x..)
|
||||
#define ICONTEXT_RIGHT_TAB (ICONTEXT_KBD_BEGIN+0x..)
|
||||
|
||||
#define COLOR_BLACK 0
|
||||
|
||||
#define COLOR_DARK_RED 35
|
||||
#define COLOR_MEDIUM_RED 36
|
||||
#define COLOR_LIGHT_RED 37 /* hgr used */
|
||||
|
||||
#define COLOR_DARK_GREEN 38
|
||||
#define COLOR_MEDIUM_GREEN 39
|
||||
#define COLOR_LIGHT_GREEN 40 /* hgr used */
|
||||
|
||||
#define COLOR_DARK_YELLOW 41
|
||||
#define COLOR_MEDIUM_YELLOW 42
|
||||
#define COLOR_LIGHT_YELLOW 43
|
||||
|
||||
#define COLOR_DARK_BLUE 44
|
||||
#define COLOR_MEDIUM_BLUE 45
|
||||
#define COLOR_LIGHT_BLUE 46 /* hgr used */
|
||||
|
||||
#define COLOR_DARK_PURPLE 47
|
||||
#define COLOR_MEDIUM_PURPLE 48
|
||||
#define COLOR_LIGHT_PURPLE 49 /* hgr used */
|
||||
|
||||
#define COLOR_DARK_CYAN 50
|
||||
#define COLOR_MEDIUM_CYAN 51
|
||||
#define COLOR_LIGHT_CYAN 52
|
||||
|
||||
#define COLOR_DARK_WHITE 53
|
||||
#define COLOR_MEDIUM_WHITE 54
|
||||
#define COLOR_LIGHT_WHITE 55
|
||||
|
||||
#define COLOR_FLASHING_BLACK 56
|
||||
#define COLOR_FLASHING_WHITE 57
|
||||
#define COLOR_FLASHING_UNGREEN 58
|
||||
#define COLOR_FLASHING_GREEN 59
|
||||
|
||||
|
||||
/* ----------------------------------
|
||||
generic graphics globals
|
||||
---------------------------------- */
|
||||
|
@ -118,7 +118,7 @@ static void _translate_screen_x_y(char *screen, const int xlen, const int ylen)
|
||||
}
|
||||
}
|
||||
|
||||
void interface_plotMessage(uint8_t *fb, const interface_colorscheme_t cs, char *message, const uint8_t message_cols, const uint8_t message_rows) {
|
||||
void interface_plotMessage(PIXEL_TYPE *fb, const interface_colorscheme_t cs, char *message, const uint8_t message_cols, const uint8_t message_rows) {
|
||||
_translate_screen_x_y(message, message_cols, message_rows);
|
||||
display_plotMessage(fb, cs, message, message_cols, message_rows);
|
||||
}
|
||||
@ -1083,7 +1083,6 @@ void c_interface_parameters()
|
||||
else if ((ch == kESC) || c_keys_is_interface_key(ch))
|
||||
{
|
||||
timing_initialize();
|
||||
display_reset();
|
||||
vm_reinitializeAudio();
|
||||
c_joystick_reset();
|
||||
#if !TESTING
|
||||
|
@ -16,42 +16,10 @@
|
||||
#ifndef A2_INTERFACE_H
|
||||
#define A2_INTERFACE_H
|
||||
|
||||
#include "display.h"
|
||||
|
||||
#define INTERFACE_SCREEN_X 80
|
||||
|
||||
typedef enum interface_colorscheme_t {
|
||||
GREEN_ON_BLACK = 0,
|
||||
GREEN_ON_BLUE,
|
||||
RED_ON_BLACK,
|
||||
BLUE_ON_BLACK,
|
||||
WHITE_ON_BLACK,
|
||||
|
||||
// WARNING : changing here requires updating display.c ncvideo.c
|
||||
|
||||
BLACK_ON_RED,
|
||||
|
||||
// 16 COLORS -- ncvideo.c
|
||||
BLACK_ON_BLACK,
|
||||
BLACK_ON_MAGENTA,
|
||||
BLACK_ON_DARKBLUE,
|
||||
BLACK_ON_PURPLE,
|
||||
BLACK_ON_DARKGREEN,
|
||||
BLACK_ON_DARKGREY,
|
||||
BLACK_ON_MEDBLUE,
|
||||
BLACK_ON_LIGHTBLUE,
|
||||
BLACK_ON_BROWN,
|
||||
BLACK_ON_ORANGE,
|
||||
BLACK_ON_LIGHTGREY,
|
||||
BLACK_ON_PINK,
|
||||
BLACK_ON_GREEN,
|
||||
BLACK_ON_YELLOW,
|
||||
BLACK_ON_AQUA,
|
||||
BLACK_ON_WHITE,
|
||||
|
||||
NUM_INTERFACE_COLORSCHEMES,
|
||||
COLOR16 = 0x80,
|
||||
INVALID_COLORSCHEME = 0xFF,
|
||||
} interface_colorscheme_t;
|
||||
|
||||
#if INTERFACE_CLASSIC
|
||||
void c_interface_begin(int current_key);
|
||||
void c_interface_print(int x, int y, const interface_colorscheme_t cs, const char *s);
|
||||
@ -66,7 +34,7 @@ bool interface_isShowing(void);
|
||||
#endif
|
||||
|
||||
// Plot message into pixel buffer
|
||||
void interface_plotMessage(uint8_t *fb, const interface_colorscheme_t cs, char *message, const uint8_t message_cols, const uint8_t message_rows);
|
||||
void interface_plotMessage(PIXEL_TYPE *fb, const interface_colorscheme_t cs, char *message, const uint8_t message_cols, const uint8_t message_rows);
|
||||
|
||||
#if INTERFACE_TOUCH
|
||||
typedef enum interface_device_t {
|
||||
|
@ -279,7 +279,7 @@ TEST test_lores_with_80col() {
|
||||
|
||||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED);
|
||||
|
||||
if (test_color_mode == COLOR_MODE_BW) {
|
||||
if (test_color_mode == COLOR_MODE_MONO) {
|
||||
WAIT_FOR_FB_SHA("DED166782E9C529B6D7DB2EEBFF5877AD49C4C1F");
|
||||
} else {
|
||||
#if !CONFORMANT_TRACKS
|
||||
@ -301,7 +301,7 @@ TEST test_lores_with_40col() {
|
||||
|
||||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED);
|
||||
|
||||
if (test_color_mode == COLOR_MODE_BW) {
|
||||
if (test_color_mode == COLOR_MODE_MONO) {
|
||||
WAIT_FOR_FB_SHA("270B44B639E062B1DC7C2EB2E561051130F5F790");
|
||||
} else {
|
||||
ASSERT_SHA_OLD("D7DC78F5718B4CF8716614E79ADABCAB919FCE5D");
|
||||
@ -322,7 +322,7 @@ TEST test_lores_with_40col_2() {
|
||||
|
||||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED);
|
||||
|
||||
if (test_color_mode == COLOR_MODE_BW) {
|
||||
if (test_color_mode == COLOR_MODE_MONO) {
|
||||
WAIT_FOR_FB_SHA("A3D5F5DF7A2DF15DDDF7E82F83B756827CD142D3");
|
||||
} else {
|
||||
WAIT_FOR_FB_SHA("D7CC29D2030230258FAFF3772C8F9AD2B318D190");
|
||||
@ -341,7 +341,7 @@ TEST test_lores_40colmix_normal() {
|
||||
|
||||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED);
|
||||
|
||||
if (test_color_mode == COLOR_MODE_BW) {
|
||||
if (test_color_mode == COLOR_MODE_MONO) {
|
||||
WAIT_FOR_FB_SHA("373799861AFCA845826C27571D2FFF7F1CB69BD6");
|
||||
} else {
|
||||
#if !CONFORMANT_TRACKS
|
||||
@ -363,7 +363,7 @@ TEST test_lores_40colmix_inverse() {
|
||||
|
||||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED);
|
||||
|
||||
if (test_color_mode == COLOR_MODE_BW) {
|
||||
if (test_color_mode == COLOR_MODE_MONO) {
|
||||
WAIT_FOR_FB_SHA("F9F4757BB751AD47D975D45DC75B3C93C9F2C6C8");
|
||||
} else {
|
||||
ASSERT_SHA_OLD("5256E8B96CB04F48324B587ECCCF8A435077B5DE");
|
||||
@ -384,7 +384,7 @@ TEST test_lores_80colmix_normal() {
|
||||
|
||||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED);
|
||||
|
||||
if (test_color_mode == COLOR_MODE_BW) {
|
||||
if (test_color_mode == COLOR_MODE_MONO) {
|
||||
WAIT_FOR_FB_SHA("DD2A3A05EA38652A86D144FFB5BD98CB24A82FF6");
|
||||
} else {
|
||||
ASSERT_SHA_OLD("9D5D5382B0A18A71DC135CAD51BEA2665ADB5FB2");
|
||||
@ -405,7 +405,7 @@ TEST test_lores_80colmix_inverse() {
|
||||
|
||||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED);
|
||||
|
||||
if (test_color_mode == COLOR_MODE_BW) {
|
||||
if (test_color_mode == COLOR_MODE_MONO) {
|
||||
WAIT_FOR_FB_SHA("0D51D6A375820FE36E4D95127F0E7A8F71495F4A");
|
||||
} else {
|
||||
ASSERT_SHA_OLD("7936E87BE1F920AACD43268DB288746528E89959");
|
||||
@ -433,7 +433,7 @@ TEST test_hires_with_80col() {
|
||||
|
||||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED);
|
||||
|
||||
if (test_color_mode == COLOR_MODE_BW) {
|
||||
if (test_color_mode == COLOR_MODE_MONO) {
|
||||
ASSERT_SHA(MOIRE_SHA_BW);
|
||||
} else {
|
||||
ASSERT_SHA(MOIRE_SHA);
|
||||
@ -451,7 +451,7 @@ TEST test_hires_with_40col() {
|
||||
|
||||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED);
|
||||
|
||||
if (test_color_mode == COLOR_MODE_BW) {
|
||||
if (test_color_mode == COLOR_MODE_MONO) {
|
||||
ASSERT_SHA(MOIRE_SHA_BW);
|
||||
} else {
|
||||
ASSERT_SHA(MOIRE_SHA);
|
||||
@ -469,7 +469,7 @@ TEST test_hires_with_40col_page2() {
|
||||
|
||||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED);
|
||||
|
||||
if (test_color_mode == COLOR_MODE_BW) {
|
||||
if (test_color_mode == COLOR_MODE_MONO) {
|
||||
WAIT_FOR_FB_SHA(MOIRE_SHA_BW);
|
||||
} else {
|
||||
WAIT_FOR_FB_SHA(MOIRE_SHA);
|
||||
@ -487,7 +487,7 @@ TEST test_hires_40colmix_normal() {
|
||||
|
||||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED);
|
||||
|
||||
if (test_color_mode == COLOR_MODE_BW) {
|
||||
if (test_color_mode == COLOR_MODE_MONO) {
|
||||
ASSERT_SHA("9611721C0F70C5F1FE0172534EC15B977CB099D4");
|
||||
} else {
|
||||
ASSERT_SHA("37F41F74EB23F8812498F732E6DA34A0EBC4D68A");
|
||||
@ -505,7 +505,7 @@ TEST test_hires_40colmix_inverse() {
|
||||
|
||||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED);
|
||||
|
||||
if (test_color_mode == COLOR_MODE_BW) {
|
||||
if (test_color_mode == COLOR_MODE_MONO) {
|
||||
ASSERT_SHA("5CFA5789735AD09FAB8CC7B6EE44CE22CF64A70D");
|
||||
} else {
|
||||
ASSERT_SHA("253D1823F5DAC0300B46B3D49C04CD59CC70076F");
|
||||
@ -523,7 +523,7 @@ TEST test_hires_80colmix_normal() {
|
||||
|
||||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED);
|
||||
|
||||
if (test_color_mode == COLOR_MODE_BW) {
|
||||
if (test_color_mode == COLOR_MODE_MONO) {
|
||||
WAIT_FOR_FB_SHA("4069102016E4E6AA860A32C6BAC5E4A6C6A45B72");
|
||||
} else {
|
||||
WAIT_FOR_FB_SHA("8D02F9A7CFC7A7E6D836B01862389F55E877E4E6");
|
||||
@ -541,7 +541,7 @@ TEST test_hires_80colmix_inverse() {
|
||||
|
||||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED);
|
||||
|
||||
if (test_color_mode == COLOR_MODE_BW) {
|
||||
if (test_color_mode == COLOR_MODE_MONO) {
|
||||
WAIT_FOR_FB_SHA("C3C19FB3258E7A58F81BC3DC51C2AEDFFC836285");
|
||||
} else {
|
||||
#if !CONFORMANT_TRACKS
|
||||
@ -566,7 +566,7 @@ TEST test_80col_lores() {
|
||||
|
||||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED);
|
||||
|
||||
if (test_color_mode == COLOR_MODE_BW) {
|
||||
if (test_color_mode == COLOR_MODE_MONO) {
|
||||
ASSERT_SHA("D8238DC3ACC1A0E191CEC06F505A159993C2EBFA");
|
||||
} else {
|
||||
ASSERT_SHA("5BFF6721FB90B3A6AF88D9021A013C007C4AF23A");
|
||||
@ -584,7 +584,7 @@ TEST test_80col_lores_2() {
|
||||
|
||||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED);
|
||||
|
||||
if (test_color_mode == COLOR_MODE_BW) {
|
||||
if (test_color_mode == COLOR_MODE_MONO) {
|
||||
ASSERT_SHA("5B99DE77F81AD8718FCFB735215A37F7B5ED5DE7");
|
||||
} else {
|
||||
ASSERT_SHA("98BB7C04854594D9E709302EF29905D2A89F1D34");
|
||||
@ -602,7 +602,7 @@ TEST test_80col_hires() {
|
||||
|
||||
ASSERT(apple_ii_64k[0][WATCHPOINT_ADDR] == TEST_FINISHED);
|
||||
|
||||
if (test_color_mode == COLOR_MODE_BW) {
|
||||
if (test_color_mode == COLOR_MODE_MONO) {
|
||||
ASSERT_SHA("647F3A377513486121C7609E3F53E97DC6FC456D");
|
||||
} else {
|
||||
ASSERT_SHA("919EBCBABEA57E932F84E9864B2C35F57F8909B4");
|
||||
@ -626,8 +626,8 @@ GREATEST_SUITE(test_suite_display) {
|
||||
static parms_t parmsArray[] = {
|
||||
{ COLOR_MODE_COLOR, true },
|
||||
{ COLOR_MODE_COLOR, false },
|
||||
{ COLOR_MODE_BW, true },
|
||||
{ COLOR_MODE_BW, false },
|
||||
{ COLOR_MODE_MONO, true },
|
||||
{ COLOR_MODE_MONO, false },
|
||||
};
|
||||
unsigned int count = sizeof(parmsArray)/sizeof(parmsArray[0]);
|
||||
|
||||
@ -755,15 +755,15 @@ GREATEST_SUITE(test_suite_display) {
|
||||
// double-lo/hi
|
||||
|
||||
RUN_TEST(test_80col_lores);
|
||||
test_color_mode = COLOR_MODE_BW;
|
||||
test_color_mode = COLOR_MODE_MONO;
|
||||
RUN_TEST(test_80col_lores);
|
||||
|
||||
RUN_TEST(test_80col_lores_2);
|
||||
test_color_mode = COLOR_MODE_BW;
|
||||
test_color_mode = COLOR_MODE_MONO;
|
||||
RUN_TEST(test_80col_lores_2);
|
||||
|
||||
RUN_TEST(test_80col_hires);
|
||||
test_color_mode = COLOR_MODE_BW;
|
||||
test_color_mode = COLOR_MODE_MONO;
|
||||
RUN_TEST(test_80col_hires);
|
||||
|
||||
// ...
|
||||
|
@ -92,11 +92,8 @@ static void _alertToModel(char *message, unsigned int messageCols, unsigned int
|
||||
hudElement->tpl = message;
|
||||
hudElement->pixWidth = fbWidth;
|
||||
hudElement->pixHeight = fbHeight;
|
||||
hudElement->pixels = MALLOC(fbWidth * fbHeight);
|
||||
if (!hudElement->pixels) {
|
||||
LOG("OOPS cannot create animation message intermediate framebuffer!");
|
||||
break;
|
||||
}
|
||||
hudElement->pixels = MALLOC(fbWidth * fbHeight * PIXEL_STRIDE);
|
||||
assert(hudElement->pixels);
|
||||
glhud_setupDefault(messageModel);
|
||||
|
||||
if (1) {
|
||||
|
@ -134,9 +134,8 @@ void *glhud_createDefault(void) {
|
||||
void *glhud_createCustom(unsigned int sizeofModel) {
|
||||
assert(sizeof(GLModelHUDElement) <= sizeofModel);
|
||||
GLModelHUDElement *hudElement = (GLModelHUDElement *)CALLOC(sizeofModel, 1);
|
||||
if (hudElement) {
|
||||
hudElement->glyphMultiplier = 1;
|
||||
}
|
||||
assert(hudElement);
|
||||
hudElement->glyphMultiplier = 1;
|
||||
return hudElement;
|
||||
}
|
||||
|
||||
@ -150,7 +149,7 @@ void glhud_setupDefault(GLModel *parent) {
|
||||
char *submenu = (char *)(hudElement->tpl);
|
||||
const unsigned int cols = hudElement->tplWidth;
|
||||
const unsigned int rows = hudElement->tplHeight;
|
||||
uint8_t *fb = hudElement->pixels;
|
||||
PIXEL_TYPE *fb = hudElement->pixels;
|
||||
|
||||
// render template into indexed fb
|
||||
interface_plotMessage(fb, hudElement->colorScheme, submenu, cols, rows);
|
||||
@ -173,14 +172,11 @@ void glhud_setupDefault(GLModel *parent) {
|
||||
#endif
|
||||
for (unsigned int i=0; i<fb_h; i++, texIdx+=texSubRowStride) {
|
||||
for (unsigned int j=0; j<fb_w; j++, srcIdx++, texIdx+=dstPointStride) {
|
||||
uint8_t value = *(fb + srcIdx);
|
||||
PIXEL_TYPE rgba = (((PIXEL_TYPE)(colormap[value].red) << SHIFT_R) |
|
||||
((PIXEL_TYPE)(colormap[value].green) << SHIFT_G) |
|
||||
((PIXEL_TYPE)(colormap[value].blue) << SHIFT_B));
|
||||
PIXEL_TYPE rgba = fb[srcIdx] & RGB_MASK;
|
||||
if (rgba == 0 && hudElement->blackIsTransparent) {
|
||||
// black remains transparent
|
||||
} else {
|
||||
rgba |= ((PIXEL_TYPE)MAX_SATURATION << SHIFT_A);
|
||||
rgba |= ((PIXEL_TYPE)MAX_SATURATION << SHIFT_A);
|
||||
}
|
||||
|
||||
// scale glyph data 1x, 2x, ...
|
||||
@ -208,10 +204,7 @@ void glhud_setupDefault(GLModel *parent) {
|
||||
#endif
|
||||
for (unsigned int i=0; i<fb_h; i++, texIdx+=texSubRowStride) {
|
||||
for (unsigned int j=0; j<fb_w; j++, srcIdx++, texIdx+=dstPointStride) {
|
||||
uint8_t value = *(fb + srcIdx);
|
||||
PIXEL_TYPE rgb = (((PIXEL_TYPE)(colormap[value].red) << SHIFT_R) |
|
||||
((PIXEL_TYPE)(colormap[value].green) << SHIFT_G) |
|
||||
((PIXEL_TYPE)(colormap[value].blue) << SHIFT_B));
|
||||
PIXEL_TYPE rgb = fb[srcIdx] & RGB_MASK;
|
||||
|
||||
unsigned int dstIdx = texIdx;
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
unsigned int tplWidth; /* template width */ \
|
||||
unsigned int tplHeight; /* template height */ \
|
||||
\
|
||||
uint8_t *pixels; /* raw indexed data */ \
|
||||
PIXEL_TYPE *pixels; /* raw indexed data */ \
|
||||
unsigned int pixWidth; /* FB width -- this is the same as GLModel.texWidth if glyphMultiplier is 1 */ \
|
||||
unsigned int pixHeight; /* FB height -- this is the same as GLModel.texHeight if glyphMultiplier is 1 */ \
|
||||
unsigned int glyphMultiplier; \
|
||||
|
@ -296,7 +296,7 @@ static void _setup_axis_hud(GLModel *parent) {
|
||||
hudElement->tplHeight = AXIS_TEMPLATE_ROWS;
|
||||
memcpy(hudElement->tpl, axisTemplate, size);
|
||||
|
||||
hudElement->pixels = CALLOC(AXIS_FB_WIDTH * AXIS_FB_HEIGHT, 1);
|
||||
hudElement->pixels = CALLOC(AXIS_FB_WIDTH * AXIS_FB_HEIGHT * PIXEL_STRIDE, 1);
|
||||
hudElement->pixWidth = AXIS_FB_WIDTH;
|
||||
hudElement->pixHeight = AXIS_FB_HEIGHT;
|
||||
}
|
||||
@ -347,7 +347,7 @@ static void _setup_button_hud(GLModel *parent) {
|
||||
hudElement->tplHeight = BUTTON_TEMPLATE_ROWS;
|
||||
memcpy(hudElement->tpl, buttonTemplate, size);
|
||||
|
||||
hudElement->pixels = CALLOC(BUTTON_FB_WIDTH * BUTTON_FB_HEIGHT, 1);
|
||||
hudElement->pixels = CALLOC(BUTTON_FB_WIDTH * BUTTON_FB_HEIGHT * PIXEL_STRIDE, 1);
|
||||
hudElement->pixWidth = BUTTON_FB_WIDTH;
|
||||
hudElement->pixHeight = BUTTON_FB_HEIGHT;
|
||||
}
|
||||
|
@ -511,7 +511,7 @@ static void *_create_touchkbd_hud(GLModel *parent) {
|
||||
|
||||
const unsigned int size = sizeof(kbdTemplateUCase/* assuming all the same dimensions */);
|
||||
hudKeyboard->tpl = MALLOC(size);
|
||||
hudKeyboard->pixels = MALLOC(KBD_FB_WIDTH * KBD_FB_HEIGHT);
|
||||
hudKeyboard->pixels = MALLOC(KBD_FB_WIDTH * KBD_FB_HEIGHT * PIXEL_STRIDE);
|
||||
|
||||
uint8_t *template = NULL;
|
||||
long lVal = 0;
|
||||
|
@ -390,7 +390,7 @@ static void *_create_touchmenu_hud(GLModel *parent) {
|
||||
|
||||
const unsigned int size = sizeof(topMenuTemplate);
|
||||
hudMenu->tpl = CALLOC(size, 1);
|
||||
hudMenu->pixels = CALLOC(MENU_FB_WIDTH * MENU_FB_HEIGHT, 1);
|
||||
hudMenu->pixels = CALLOC(MENU_FB_WIDTH * MENU_FB_HEIGHT * PIXEL_STRIDE, 1);
|
||||
|
||||
_present_menu(parent);
|
||||
|
||||
|
@ -316,21 +316,10 @@ static void glvideo_render(void) {
|
||||
#endif
|
||||
|
||||
unsigned long wasDirty = video_clearDirty(FB_DIRTY_FLAG);
|
||||
char *pixels = (char *)crtModel->texPixels;
|
||||
GLvoid *pixels = crtModel->texPixels;
|
||||
if (wasDirty) {
|
||||
uint8_t *fb = display_getCurrentFramebuffer();
|
||||
SCOPE_TRACE_VIDEO("pixel convert");
|
||||
// Update texture from indexed-color Apple //e internal framebuffer
|
||||
unsigned int count = SCANWIDTH * SCANHEIGHT;
|
||||
for (unsigned int i=0, j=0; i<count; i++, j+=sizeof(PIXEL_TYPE)) {
|
||||
uint8_t index = *(fb + i);
|
||||
*( (PIXEL_TYPE*)(pixels + j) ) = (PIXEL_TYPE)(
|
||||
((PIXEL_TYPE)(colormap[index].red) << SHIFT_R) |
|
||||
((PIXEL_TYPE)(colormap[index].green) << SHIFT_G) |
|
||||
((PIXEL_TYPE)(colormap[index].blue) << SHIFT_B) |
|
||||
((PIXEL_TYPE)MAX_SATURATION << SHIFT_A)
|
||||
);
|
||||
}
|
||||
void *fb = display_getCurrentFramebuffer();
|
||||
memcpy(/*dest:*/crtModel->texPixels, /*src:*/fb, (SCANWIDTH*SCANHEIGHT*sizeof(PIXEL_TYPE)));
|
||||
}
|
||||
|
||||
glActiveTexture(TEXTURE_ACTIVE_FRAMEBUFFER);
|
||||
@ -339,7 +328,7 @@ static void glvideo_render(void) {
|
||||
if (wasDirty) {
|
||||
SCOPE_TRACE_VIDEO("glvideo texImage2D");
|
||||
_HACKAROUND_GLTEXIMAGE2D_PRE(TEXTURE_ACTIVE_FRAMEBUFFER, crtModel->textureName);
|
||||
glTexImage2D(GL_TEXTURE_2D, /*level*/0, TEX_FORMAT_INTERNAL, SCANWIDTH, SCANHEIGHT, /*border*/0, TEX_FORMAT, TEX_TYPE, (GLvoid *)&pixels[0]);
|
||||
glTexImage2D(GL_TEXTURE_2D, /*level*/0, TEX_FORMAT_INTERNAL, SCANWIDTH, SCANHEIGHT, /*border*/0, TEX_FORMAT, TEX_TYPE, pixels);
|
||||
}
|
||||
|
||||
// Bind our vertex array object
|
||||
|
435
src/video/ntsc.c
Normal file
435
src/video/ntsc.c
Normal file
@ -0,0 +1,435 @@
|
||||
/*
|
||||
* Apple // emulator for *ix
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 3 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* Copyright 2018 Aaron Culliney
|
||||
*
|
||||
*/
|
||||
|
||||
// NOTE: routines here are copied from William (Sheldon) Simms's NTSC implementation in AppleWin
|
||||
// TODO: implement these in a shader?
|
||||
|
||||
/*
|
||||
AppleWin : An Apple //e emulator for Windows
|
||||
|
||||
Copyright (C) 2010-2011, William S Simms
|
||||
Copyright (C) 2014-2016, Michael Pohoreski, Tom Charlesworth
|
||||
|
||||
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 "common.h"
|
||||
#include "video/ntsc.h"
|
||||
|
||||
#define NTSC_NUM_PHASES 4
|
||||
#define NTSC_NUM_SEQUENCES 4096
|
||||
|
||||
typedef void (*fb_plotter_fn)(color_mode_t, uint16_t, PIXEL_TYPE *);
|
||||
typedef PIXEL_TYPE (*fb_scanline_fn)(PIXEL_TYPE color0, PIXEL_TYPE color2);
|
||||
|
||||
static uint8_t half_scanlines = false;
|
||||
static fb_plotter_fn pixelPlotter[NUM_COLOROPTS] = { NULL };
|
||||
static fb_scanline_fn getHalfColor[NUM_COLOROPTS][2] = { NULL };
|
||||
|
||||
static unsigned int ntsc_color_phase = 0;
|
||||
unsigned int ntsc_signal_bits = 0;
|
||||
|
||||
static PIXEL_TYPE monoPixelsMonitor [NTSC_NUM_SEQUENCES];
|
||||
static PIXEL_TYPE monoPixelsTV [NTSC_NUM_SEQUENCES];
|
||||
|
||||
static PIXEL_TYPE colorPixelsMonitor[NTSC_NUM_PHASES][NTSC_NUM_SEQUENCES];
|
||||
static PIXEL_TYPE colorPixelsTV [NTSC_NUM_PHASES][NTSC_NUM_SEQUENCES];
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// TV pixel updates
|
||||
|
||||
static PIXEL_TYPE halfScanlineTV(PIXEL_TYPE color0, PIXEL_TYPE color2) {
|
||||
PIXEL_TYPE color1;
|
||||
|
||||
int r = (color0 >> SHIFT_R) & 0xFF;
|
||||
int g = (color0 >> SHIFT_G) & 0xFF;
|
||||
int b = (color0 >> SHIFT_B) & 0xFF;
|
||||
uint32_t color2_prime = (color2 & 0xFCFCFCFC) >> 2;
|
||||
r -= (color2_prime >> SHIFT_R) & 0xFF; if (r<0) { r=0; } // clamp to 0 on underflow
|
||||
g -= (color2_prime >> SHIFT_G) & 0xFF; if (g<0) { g=0; } // clamp to 0 on underflow
|
||||
b -= (color2_prime >> SHIFT_B) & 0xFF; if (b<0) { b=0; } // clamp to 0 on underflow
|
||||
color1 = (r<<SHIFT_R) | (g<<SHIFT_G) | (b<<SHIFT_B) | (0xFF<<SHIFT_A);
|
||||
|
||||
return color1;
|
||||
}
|
||||
|
||||
static PIXEL_TYPE doubleScanlineTV(PIXEL_TYPE color0, PIXEL_TYPE color2) {
|
||||
PIXEL_TYPE color1 = ((color0 & 0xFEFEFEFE) >> 1) + ((color2 & 0xFEFEFEFE) >> 1); // 50% Blend
|
||||
return color1 | (0xFF<<SHIFT_A);
|
||||
}
|
||||
|
||||
static void updateFBCommon(color_mode_t mode, uint16_t signal, PIXEL_TYPE *fb_ptr, PIXEL_TYPE *color_table) {
|
||||
PIXEL_TYPE *fb_ptr0 = fb_ptr;
|
||||
PIXEL_TYPE *fb_ptr1 = fb_ptr + (SCANWIDTH<<0);
|
||||
PIXEL_TYPE *fb_ptr2 = fb_ptr + (SCANWIDTH<<1);
|
||||
|
||||
PIXEL_TYPE color0;
|
||||
{
|
||||
ntsc_signal_bits = ((ntsc_signal_bits << 1) | signal) & 0xFFF; // 12-bit ?
|
||||
color0 = color_table[ntsc_signal_bits];
|
||||
}
|
||||
PIXEL_TYPE color2 = *fb_ptr2;
|
||||
PIXEL_TYPE color1 = getHalfColor[mode][half_scanlines](color0, color2);
|
||||
|
||||
*fb_ptr0 = color0;
|
||||
*fb_ptr1 = color1;
|
||||
|
||||
++ntsc_color_phase;
|
||||
ntsc_color_phase &= 3;
|
||||
}
|
||||
|
||||
static void updateFBMonoTV(color_mode_t mode, uint16_t signal, PIXEL_TYPE *fb_ptr) {
|
||||
updateFBCommon(mode, signal, fb_ptr, monoPixelsTV);
|
||||
}
|
||||
|
||||
static void updateFBColorTV(color_mode_t mode, uint16_t signal, PIXEL_TYPE *fb_ptr) {
|
||||
updateFBCommon(mode, signal, fb_ptr, colorPixelsTV[ntsc_color_phase]);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Monitor pixel updates
|
||||
|
||||
static PIXEL_TYPE halfScanlineMonitor(PIXEL_TYPE color0, PIXEL_TYPE color2) {
|
||||
(void)color2;
|
||||
PIXEL_TYPE color1 = ((color0 & 0xFCFCFCFC) >> 2) | (0xFF << SHIFT_A);
|
||||
return color1;
|
||||
}
|
||||
|
||||
static PIXEL_TYPE doubleScanlineMonitor(PIXEL_TYPE color0, PIXEL_TYPE color2) {
|
||||
(void)color2;
|
||||
return color0;
|
||||
}
|
||||
|
||||
static void updateFBMonoMonitor(color_mode_t mode, uint16_t signal, PIXEL_TYPE *fb_ptr) {
|
||||
updateFBCommon(mode, signal, fb_ptr, monoPixelsMonitor);
|
||||
}
|
||||
|
||||
static void updateFBColorMonitor(color_mode_t mode, uint16_t signal, PIXEL_TYPE *fb_ptr) {
|
||||
updateFBCommon(mode, signal, fb_ptr, colorPixelsMonitor[ntsc_color_phase]);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
void ntsc_plotBits(color_mode_t mode, uint16_t bits14, PIXEL_TYPE *fb_ptr) {
|
||||
assert(!(mode == COLOR_MODE_COLOR || mode == COLOR_MODE_INTERP));
|
||||
|
||||
pixelPlotter[mode](mode, bits14 & 1, fb_ptr); bits14 >>= 1; ++fb_ptr;
|
||||
pixelPlotter[mode](mode, bits14 & 1, fb_ptr); bits14 >>= 1; ++fb_ptr;
|
||||
|
||||
pixelPlotter[mode](mode, bits14 & 1, fb_ptr); bits14 >>= 1; ++fb_ptr;
|
||||
pixelPlotter[mode](mode, bits14 & 1, fb_ptr); bits14 >>= 1; ++fb_ptr;
|
||||
|
||||
pixelPlotter[mode](mode, bits14 & 1, fb_ptr); bits14 >>= 1; ++fb_ptr;
|
||||
pixelPlotter[mode](mode, bits14 & 1, fb_ptr); bits14 >>= 1; ++fb_ptr;
|
||||
|
||||
pixelPlotter[mode](mode, bits14 & 1, fb_ptr); bits14 >>= 1; ++fb_ptr;
|
||||
pixelPlotter[mode](mode, bits14 & 1, fb_ptr); bits14 >>= 1; ++fb_ptr;
|
||||
|
||||
pixelPlotter[mode](mode, bits14 & 1, fb_ptr); bits14 >>= 1; ++fb_ptr;
|
||||
pixelPlotter[mode](mode, bits14 & 1, fb_ptr); bits14 >>= 1; ++fb_ptr;
|
||||
|
||||
pixelPlotter[mode](mode, bits14 & 1, fb_ptr); bits14 >>= 1; ++fb_ptr;
|
||||
pixelPlotter[mode](mode, bits14 & 1, fb_ptr); bits14 >>= 1; ++fb_ptr;
|
||||
|
||||
pixelPlotter[mode](mode, bits14 & 1, fb_ptr); bits14 >>= 1; ++fb_ptr;
|
||||
pixelPlotter[mode](mode, bits14 & 1, fb_ptr); ++fb_ptr;
|
||||
}
|
||||
|
||||
void ntsc_flushScanline(void) {
|
||||
ntsc_color_phase = 0;
|
||||
ntsc_signal_bits = 0;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// pixel color creation
|
||||
|
||||
#define CHROMA_ZEROS 2
|
||||
#define CHROMA_POLES 2
|
||||
#define CHROMA_GAIN 7.438011255f // Should this be 7.15909 MHz ?
|
||||
#define CHROMA_0 -0.7318893645f
|
||||
#define CHROMA_1 1.2336442711f
|
||||
|
||||
#define LUMA_ZEROS 2
|
||||
#define LUMA_POLES 2
|
||||
#define LUMA_GAIN 13.71331570f // Should this be 14.318180 MHz ?
|
||||
#define LUMA_0 -0.3961075449f
|
||||
#define LUMA_1 1.1044202472f
|
||||
|
||||
#define SIGNAL_ZEROS 2
|
||||
#define SIGNAL_POLES 2
|
||||
#define SIGNAL_GAIN 7.614490548f // Should this be 7.15909 MHz ?
|
||||
#define SIGNAL_0 -0.2718798058f
|
||||
#define SIGNAL_1 0.7465656072f
|
||||
|
||||
#if !defined(M_PI)
|
||||
# error M_PI not defined on this platform?
|
||||
# define M_PI 3.1415926535898f
|
||||
#endif
|
||||
|
||||
#define DEG_TO_RAD(x) (M_PI*(x)/180.f)
|
||||
#define RAD_45 (M_PI*0.25f)
|
||||
#define RAD_90 (M_PI*0.5f)
|
||||
#define RAD_360 (M_PI*2.f)
|
||||
|
||||
#define CYCLESTART (DEG_TO_RAD(45))
|
||||
|
||||
#define clampZeroOne(x) ({ \
|
||||
typeof(x) _rc = x; \
|
||||
if (_rc < 0.f) { _rc = 0.f; } \
|
||||
if (_rc > 1.f) { _rc = 1.f; } \
|
||||
_rc; \
|
||||
})
|
||||
|
||||
// What filter is this ??
|
||||
// Filter Order: 2 -> poles for low pass
|
||||
static double initFilterChroma(double z) {
|
||||
static double x[CHROMA_ZEROS + 1] = {0,0,0};
|
||||
static double y[CHROMA_POLES + 1] = {0,0,0};
|
||||
|
||||
x[0] = x[1]; x[1] = x[2]; x[2] = z / CHROMA_GAIN;
|
||||
y[0] = y[1]; y[1] = y[2]; y[2] = -x[0] + x[2] + (CHROMA_0*y[0]) + (CHROMA_1*y[1]); // inverted x[0]
|
||||
|
||||
return y[2];
|
||||
}
|
||||
|
||||
// Butterworth Lowpass digital filter
|
||||
// Filter Order: 2 -> poles for low pass
|
||||
static double initFilterLuma0(double z) {
|
||||
static double x[LUMA_ZEROS + 1] = { 0,0,0 };
|
||||
static double y[LUMA_POLES + 1] = { 0,0,0 };
|
||||
|
||||
x[0] = x[1]; x[1] = x[2]; x[2] = z / LUMA_GAIN;
|
||||
y[0] = y[1]; y[1] = y[2]; y[2] = x[0] + x[2] + (2.f*x[1]) + (LUMA_0*y[0]) + (LUMA_1*y[1]);
|
||||
|
||||
return y[2];
|
||||
}
|
||||
|
||||
// Butterworth Lowpass digital filter
|
||||
// Filter Order: 2 -> poles for low pass
|
||||
static double initFilterLuma1(double z) {
|
||||
static double x[LUMA_ZEROS + 1] = { 0,0,0};
|
||||
static double y[LUMA_POLES + 1] = { 0,0,0};
|
||||
|
||||
x[0] = x[1]; x[1] = x[2]; x[2] = z / LUMA_GAIN;
|
||||
y[0] = y[1]; y[1] = y[2]; y[2] = x[0] + x[2] + (2.f*x[1]) + (LUMA_0*y[0]) + (LUMA_1*y[1]);
|
||||
|
||||
return y[2];
|
||||
}
|
||||
|
||||
// Butterworth Lowpass digital filter
|
||||
// Filter Order: 2 -> poles for low pass
|
||||
static double initFilterSignal(double z) {
|
||||
static double x[SIGNAL_ZEROS + 1] = { 0,0,0 };
|
||||
static double y[SIGNAL_POLES + 1] = { 0,0,0 };
|
||||
|
||||
x[0] = x[1]; x[1] = x[2]; x[2] = z / SIGNAL_GAIN;
|
||||
y[0] = y[1]; y[1] = y[2]; y[2] = x[0] + x[2] + (2.f*x[1]) + (SIGNAL_0*y[0]) + (SIGNAL_1*y[1]);
|
||||
|
||||
return y[2];
|
||||
}
|
||||
|
||||
// Build the 4 phase chroma lookup table
|
||||
// The YI'Q' colors are hard-coded
|
||||
static void initChromaPhaseTables(color_mode_t color_mode, mono_mode_t mono_mode) {
|
||||
int phase,s,t,n;
|
||||
double z = 0;
|
||||
double y0,y1,c,i,q = 0;
|
||||
double phi,zz;
|
||||
float brightness;
|
||||
double r64,g64,b64;
|
||||
float r32,g32,b32;
|
||||
|
||||
for (phase = 0; phase < 4; phase++) {
|
||||
phi = (phase * RAD_90) + CYCLESTART;
|
||||
for (s = 0; s < NTSC_NUM_SEQUENCES; s++) {
|
||||
t = s;
|
||||
y0 = y1 = c = i = q = 0.0;
|
||||
|
||||
for (n = 0; n < 12; n++) {
|
||||
z = (double)(0 != (t & 0x800));
|
||||
t = t << 1;
|
||||
|
||||
for (unsigned int k = 0; k < 2; k++) {
|
||||
//z = z * 1.25;
|
||||
zz = initFilterSignal(z);
|
||||
c = initFilterChroma(zz); // "Mostly" correct _if_ CYCLESTART = PI/4 = 45 degrees
|
||||
y0 = initFilterLuma0 (zz);
|
||||
y1 = initFilterLuma1 (zz - c);
|
||||
|
||||
c = c * 2.f;
|
||||
i = i + (c * cos(phi) - i) / 8.f;
|
||||
q = q + (c * sin(phi) - q) / 8.f;
|
||||
|
||||
phi += RAD_45;
|
||||
} // k
|
||||
} // samples
|
||||
|
||||
brightness = clampZeroOne((float)z);
|
||||
if (color_mode == COLOR_MODE_MONO && mono_mode == MONO_MODE_GREEN) {
|
||||
monoPixelsMonitor[s] = (((uint8_t)(brightness * 0xFF)) << SHIFT_G) | (0x00 << SHIFT_R) | (0x00 << SHIFT_B) | (0xFF << SHIFT_A);
|
||||
brightness = clampZeroOne((float)y1);
|
||||
monoPixelsTV[s] = (((uint8_t)(brightness * 0xFF)) << SHIFT_G) | (0x00 << SHIFT_R) | (0x00 << SHIFT_B) | (0xFF << SHIFT_A);
|
||||
} else {
|
||||
monoPixelsMonitor[s] = (((uint8_t)(brightness * 0xFF)) << SHIFT_R) |
|
||||
(((uint8_t)(brightness * 0xFF)) << SHIFT_G) |
|
||||
(((uint8_t)(brightness * 0xFF)) << SHIFT_B) |
|
||||
(0xFF << SHIFT_A);
|
||||
|
||||
brightness = clampZeroOne((float)y1);
|
||||
monoPixelsTV[s] = (((uint8_t)(brightness * 0xFF)) << SHIFT_R) |
|
||||
(((uint8_t)(brightness * 0xFF)) << SHIFT_G) |
|
||||
(((uint8_t)(brightness * 0xFF)) << SHIFT_B) |
|
||||
(0xFF << SHIFT_A);
|
||||
}
|
||||
|
||||
/*
|
||||
YI'V' to RGB
|
||||
[r g b] = [y i v][ 1 1 1 ]
|
||||
[0.956 -0.272 -1.105]
|
||||
[0.621 -0.647 1.702]
|
||||
[r] [1 0.956 0.621][y]
|
||||
[g] = [1 -0.272 -0.647][i]
|
||||
[b] [1 -1.105 1.702][v]
|
||||
*/
|
||||
#define I_TO_R 0.956f
|
||||
#define I_TO_G -0.272f
|
||||
#define I_TO_B -1.105f
|
||||
|
||||
#define Q_TO_R 0.621f
|
||||
#define Q_TO_G -0.647f
|
||||
#define Q_TO_B 1.702f
|
||||
|
||||
r64 = y0 + (I_TO_R * i) + (Q_TO_R * q);
|
||||
g64 = y0 + (I_TO_G * i) + (Q_TO_G * q);
|
||||
b64 = y0 + (I_TO_B * i) + (Q_TO_B * q);
|
||||
|
||||
r32 = clampZeroOne((float)r64);
|
||||
g32 = clampZeroOne((float)g64);
|
||||
b32 = clampZeroOne((float)b64);
|
||||
|
||||
int color = s & 15;
|
||||
|
||||
// NTSC_REMOVE_WHITE_RINGING
|
||||
if (color == IDX_WHITE) {
|
||||
r32 = 1;
|
||||
g32 = 1;
|
||||
b32 = 1;
|
||||
}
|
||||
|
||||
// NTSC_REMOVE_BLACK_GHOSTING
|
||||
if (color == IDX_BLACK) {
|
||||
r32 = 0;
|
||||
g32 = 0;
|
||||
b32 = 0;
|
||||
}
|
||||
|
||||
// NTSC_REMOVE_GRAY_CHROMA
|
||||
if (color == IDX_DARKGREY) {
|
||||
const float g = (float) 0x83 / (float) 0xFF;
|
||||
r32 = g;
|
||||
g32 = g;
|
||||
b32 = g;
|
||||
}
|
||||
|
||||
if (color == IDX_LIGHTGREY) { // Gray2 & Gray1
|
||||
const float g = (float) 0x78 / (float) 0xFF;
|
||||
r32 = g;
|
||||
g32 = g;
|
||||
b32 = g;
|
||||
}
|
||||
|
||||
colorPixelsMonitor[phase][s] = (((uint8_t)(r32 * 255)) << SHIFT_R) |
|
||||
(((uint8_t)(g32 * 255)) << SHIFT_G) |
|
||||
(((uint8_t)(b32 * 255)) << SHIFT_B) |
|
||||
(0xFF << SHIFT_A);
|
||||
|
||||
r64 = y1 + (I_TO_R * i) + (Q_TO_R * q);
|
||||
g64 = y1 + (I_TO_G * i) + (Q_TO_G * q);
|
||||
b64 = y1 + (I_TO_B * i) + (Q_TO_B * q);
|
||||
|
||||
r32 = clampZeroOne((float)r64);
|
||||
g32 = clampZeroOne((float)g64);
|
||||
b32 = clampZeroOne((float)b64);
|
||||
|
||||
// NTSC_REMOVE_WHITE_RINGING
|
||||
if (color == IDX_WHITE) {
|
||||
r32 = 1;
|
||||
g32 = 1;
|
||||
b32 = 1;
|
||||
}
|
||||
|
||||
// NTSC_REMOVE_BLACK_GHOSTING
|
||||
if (color == IDX_BLACK) {
|
||||
r32 = 0;
|
||||
g32 = 0;
|
||||
b32 = 0;
|
||||
}
|
||||
|
||||
colorPixelsTV[phase][s] = (((uint8_t)(r32 * 255)) << SHIFT_R) |
|
||||
(((uint8_t)(g32 * 255)) << SHIFT_G) |
|
||||
(((uint8_t)(b32 * 255)) << SHIFT_B) |
|
||||
(0xFF << SHIFT_A);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
static void ntsc_prefsChanged(const char *domain) {
|
||||
|
||||
long lVal = 0;
|
||||
color_mode_t color_mode = prefs_parseLongValue(domain, PREF_COLOR_MODE, &lVal, /*base:*/10) ? getColorMode(lVal) : COLOR_MODE_DEFAULT;
|
||||
|
||||
lVal = MONO_MODE_BW;
|
||||
mono_mode_t mono_mode = prefs_parseLongValue(domain, PREF_MONO_MODE, &lVal, /*base:*/10) ? getMonoMode(lVal) : MONO_MODE_DEFAULT;
|
||||
|
||||
bool bVal = false;
|
||||
half_scanlines = prefs_parseBoolValue(domain, PREF_SHOW_HALF_SCANLINES, &bVal) ? (bVal ? 1 : 0) : 0;
|
||||
|
||||
initChromaPhaseTables(color_mode, mono_mode);
|
||||
}
|
||||
|
||||
static void _init_ntsc(void) {
|
||||
LOG("Initializing NTSC renderer");
|
||||
initChromaPhaseTables(COLOR_MODE_DEFAULT, MONO_MODE_DEFAULT);
|
||||
|
||||
pixelPlotter[COLOR_MODE_MONO] = updateFBMonoMonitor;
|
||||
pixelPlotter[COLOR_MODE_COLOR_MONITOR] = updateFBColorMonitor;
|
||||
pixelPlotter[COLOR_MODE_MONO_TV] = updateFBMonoTV;
|
||||
pixelPlotter[COLOR_MODE_COLOR_TV] = updateFBColorTV;
|
||||
|
||||
getHalfColor[COLOR_MODE_MONO][0] = doubleScanlineMonitor;
|
||||
getHalfColor[COLOR_MODE_MONO][1] = halfScanlineMonitor;
|
||||
getHalfColor[COLOR_MODE_COLOR_MONITOR][0] = doubleScanlineMonitor;
|
||||
getHalfColor[COLOR_MODE_COLOR_MONITOR][1] = halfScanlineMonitor;
|
||||
getHalfColor[COLOR_MODE_MONO_TV][0] = doubleScanlineTV;
|
||||
getHalfColor[COLOR_MODE_MONO_TV][1] = halfScanlineTV;
|
||||
getHalfColor[COLOR_MODE_COLOR_TV][0] = doubleScanlineTV;
|
||||
getHalfColor[COLOR_MODE_COLOR_TV][1] = halfScanlineTV;
|
||||
|
||||
prefs_registerListener(PREF_DOMAIN_VIDEO, &ntsc_prefsChanged);
|
||||
}
|
||||
|
||||
static __attribute__((constructor)) void __init_ntsc(void) {
|
||||
emulator_registerStartupCallback(CTOR_PRIORITY_LATE, &_init_ntsc);
|
||||
}
|
22
src/video/ntsc.h
Normal file
22
src/video/ntsc.h
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Apple // emulator for *ix
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 3 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* Copyright 2018 Aaron Culliney
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef A2_NTSC_H
|
||||
#define A2_NTSC_H
|
||||
|
||||
#include "common.h"
|
||||
|
||||
void ntsc_plotBits(color_mode_t mode, uint16_t bits, PIXEL_TYPE *fb_ptr);
|
||||
|
||||
void ntsc_flushScanline(void);
|
||||
|
||||
#endif /* A2_NTSC_H */
|
||||
|
@ -48,22 +48,10 @@
|
||||
#define TEX_FORMAT GL_RGBA
|
||||
|
||||
#if USE_RGBA4444
|
||||
# define PIXEL_TYPE uint16_t
|
||||
# define MAX_SATURATION 0xf
|
||||
# define SHIFT_R 12
|
||||
# define SHIFT_G 8
|
||||
# define SHIFT_B 4
|
||||
# define SHIFT_A 0
|
||||
# define TEX_FORMAT_INTERNAL GL_RGBA4
|
||||
# define TEX_TYPE GL_UNSIGNED_SHORT_4_4_4_4
|
||||
#else
|
||||
// assuming RGBA8888 ...
|
||||
# define PIXEL_TYPE uint32_t
|
||||
# define MAX_SATURATION 0xff
|
||||
# define SHIFT_R 0
|
||||
# define SHIFT_G 8
|
||||
# define SHIFT_B 16
|
||||
# define SHIFT_A 24
|
||||
# define TEX_FORMAT_INTERNAL TEX_FORMAT
|
||||
# define TEX_TYPE GL_UNSIGNED_BYTE
|
||||
#endif
|
||||
|
33
src/vm.c
33
src/vm.c
@ -1130,9 +1130,6 @@ static void _initialize_tables(void) {
|
||||
}
|
||||
|
||||
// initialize first text & hires page, which are specially bank switched
|
||||
//
|
||||
// display_reset() below substitutes it's own hooks for all visible write locations affect the display, leaving our
|
||||
// write-functions in place only at the `screen holes', hence the name.
|
||||
for (unsigned int i = 0x400; i < 0x800; i++) {
|
||||
cpu65_vmem_r[i] = iie_read_ram_text_page0;
|
||||
cpu65_vmem_w[i] = video__write_2e_text0;
|
||||
@ -1143,6 +1140,34 @@ static void _initialize_tables(void) {
|
||||
cpu65_vmem_w[i] = video__write_2e_hgr0;
|
||||
}
|
||||
|
||||
// initialize text/lores & hires graphics routines
|
||||
for (unsigned int y = 0; y < TEXT_ROWS; y++) {
|
||||
uint16_t row = display_getVideoLineOffset(y);
|
||||
for (unsigned int x = 0; x < TEXT_COLS; x++) {
|
||||
unsigned int idx = row + x;
|
||||
// text/lores pages
|
||||
if (y < 20) {
|
||||
cpu65_vmem_w[idx+0x400] = video__write_2e_text0;
|
||||
cpu65_vmem_w[idx+0x800] = video__write_2e_text1;
|
||||
} else {
|
||||
cpu65_vmem_w[idx+0x400] = video__write_2e_text0_mixed;
|
||||
cpu65_vmem_w[idx+0x800] = video__write_2e_text1_mixed;
|
||||
}
|
||||
|
||||
// hires/dhires pages
|
||||
for (unsigned int i = 0; i < 8; i++) {
|
||||
idx = row + (0x400*i) + x;
|
||||
if (y < 20) {
|
||||
cpu65_vmem_w[idx+0x2000] = video__write_2e_hgr0;
|
||||
cpu65_vmem_w[idx+0x4000] = video__write_2e_hgr1;
|
||||
} else {
|
||||
cpu65_vmem_w[idx+0x2000] = video__write_2e_hgr0_mixed;
|
||||
cpu65_vmem_w[idx+0x4000] = video__write_2e_hgr1_mixed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// softswich rom
|
||||
for (unsigned int i = 0xC000; i < 0xC100; i++) {
|
||||
cpu65_vmem_r[i] = read_unmapped_softswitch;
|
||||
@ -1297,8 +1322,6 @@ static void _initialize_tables(void) {
|
||||
cpu65_vmem_r[i] = iie_read_slot_expansion;
|
||||
}
|
||||
|
||||
display_reset();
|
||||
|
||||
// Peripheral card slot initializations ...
|
||||
|
||||
// HACK TODO FIXME : this needs to be tied to the UI/configuration system (once we have more/conflicting options)
|
||||
|
Loading…
x
Reference in New Issue
Block a user