├── settings.gradle
├── .gitignore
├── app
├── src
│ └── main
│ │ ├── assets
│ │ └── data-2.6.9.zip
│ │ ├── res
│ │ ├── drawable
│ │ │ └── download.png
│ │ ├── drawable-xxhdpi
│ │ │ ├── icon.png
│ │ │ ├── start.png
│ │ │ ├── ic_launcher.png
│ │ │ └── my_border.xml
│ │ ├── drawable-hdpi
│ │ │ └── ic_launcher.png
│ │ ├── drawable-mdpi
│ │ │ └── ic_launcher.png
│ │ ├── drawable-xhdpi
│ │ │ └── ic_launcher.png
│ │ ├── values
│ │ │ ├── styles.xml
│ │ │ └── strings.xml
│ │ ├── values-v21
│ │ │ └── styles.xml
│ │ ├── layout
│ │ │ ├── spinner_row.xml
│ │ │ ├── main.xml
│ │ │ ├── fragment_misc.xml
│ │ │ ├── fragment_hardware.xml
│ │ │ └── fragment_storage.xml
│ │ ├── menu
│ │ │ └── menu.xml
│ │ ├── values-zh-rCN
│ │ │ └── strings.xml
│ │ ├── raw
│ │ │ └── data_json
│ │ └── layout-land
│ │ │ ├── fragment_misc.xml
│ │ │ ├── fragment_hardware.xml
│ │ │ └── fragment_storage.xml
│ │ ├── java
│ │ └── net
│ │ │ └── sourceforge
│ │ │ └── bochs
│ │ │ ├── SDLActivity.java
│ │ │ ├── entity
│ │ │ ├── SoundCard.java
│ │ │ ├── VgaCard.java
│ │ │ ├── EthernetCard.java
│ │ │ └── CpuModel.java
│ │ │ ├── adapter
│ │ │ └── TabsPagerAdapter.java
│ │ │ ├── FileChooser.java
│ │ │ ├── MiscTabFragment.java
│ │ │ ├── MainActivity.java
│ │ │ ├── DirectoryChooserDialog.java
│ │ │ ├── Config.java
│ │ │ ├── StorageTabFragment.java
│ │ │ └── HardwareTabFragment.java
│ │ └── AndroidManifest.xml
├── build.gradle
├── proguard-rules.pro
└── app.iml
├── screenshots
├── bochs-portrait-misc-tab.png
├── bochs-landscape-storage-tab.png
├── bochs-portrait-hardware-tab.png
├── bochs-portrait-storage-tab.png
└── bochs-landscape-hardware-tab.png
├── setSymlinkToBochsApp.sh
├── .idea
└── libraries
│ ├── support_v4_25_1_0.xml
│ ├── support_annotations_25_1_0.xml
│ ├── support_compat_25_1_0.xml
│ ├── support_core_ui_25_1_0.xml
│ ├── support_fragment_25_1_0.xml
│ ├── support_core_utils_25_1_0.xml
│ └── support_media_compat_25_1_0.xml
└── bochsApp
├── build.gradle
└── AndroidManifest.xml
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 | include ':bochsApp'
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 | /.idea
3 | /app/build
4 | /app/app.iml
5 |
--------------------------------------------------------------------------------
/app/src/main/assets/data-2.6.9.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lubomyr/BochsLauncher/HEAD/app/src/main/assets/data-2.6.9.zip
--------------------------------------------------------------------------------
/app/src/main/res/drawable/download.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lubomyr/BochsLauncher/HEAD/app/src/main/res/drawable/download.png
--------------------------------------------------------------------------------
/screenshots/bochs-portrait-misc-tab.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lubomyr/BochsLauncher/HEAD/screenshots/bochs-portrait-misc-tab.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lubomyr/BochsLauncher/HEAD/app/src/main/res/drawable-xxhdpi/icon.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/start.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lubomyr/BochsLauncher/HEAD/app/src/main/res/drawable-xxhdpi/start.png
--------------------------------------------------------------------------------
/screenshots/bochs-landscape-storage-tab.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lubomyr/BochsLauncher/HEAD/screenshots/bochs-landscape-storage-tab.png
--------------------------------------------------------------------------------
/screenshots/bochs-portrait-hardware-tab.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lubomyr/BochsLauncher/HEAD/screenshots/bochs-portrait-hardware-tab.png
--------------------------------------------------------------------------------
/screenshots/bochs-portrait-storage-tab.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lubomyr/BochsLauncher/HEAD/screenshots/bochs-portrait-storage-tab.png
--------------------------------------------------------------------------------
/screenshots/bochs-landscape-hardware-tab.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lubomyr/BochsLauncher/HEAD/screenshots/bochs-landscape-hardware-tab.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lubomyr/BochsLauncher/HEAD/app/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lubomyr/BochsLauncher/HEAD/app/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lubomyr/BochsLauncher/HEAD/app/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/lubomyr/BochsLauncher/HEAD/app/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/java/net/sourceforge/bochs/SDLActivity.java:
--------------------------------------------------------------------------------
1 | package net.sourceforge.bochs;
2 |
3 | public class SDLActivity extends net.sourceforge.bochs.core.MainActivity {
4 | }
5 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
--------------------------------------------------------------------------------
/setSymlinkToBochsApp.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | ln -s ~/androidsdl/project/src bochsApp/src
4 | ln -s ~/androidsdl/project/res bochsApp/res
5 | ln -s ~/androidsdl/project/libs app/src/main/jniLibs
--------------------------------------------------------------------------------
/app/src/main/res/values-v21/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/spinner_row.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/support_v4_25_1_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/menu.xml:
--------------------------------------------------------------------------------
1 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/my_border.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
9 |
10 |
11 |
12 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/main.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/app/src/main/java/net/sourceforge/bochs/entity/SoundCard.java:
--------------------------------------------------------------------------------
1 | package net.sourceforge.bochs.entity;
2 |
3 | public class SoundCard {
4 | private String value;
5 | private String description;
6 |
7 | public SoundCard(String value, String description) {
8 | this.value = value;
9 | this.description = description;
10 | }
11 |
12 | public void setValue(String value) {
13 | this.value = value;
14 | }
15 |
16 | public String getValue() {
17 | return value;
18 | }
19 |
20 | public void setDescription(String description) {
21 | this.description = description;
22 | }
23 |
24 | public String getDescription() {
25 | return description;
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/java/net/sourceforge/bochs/entity/VgaCard.java:
--------------------------------------------------------------------------------
1 | package net.sourceforge.bochs.entity;
2 |
3 | public class VgaCard {
4 | private String value;
5 | private String description;
6 |
7 | public VgaCard(String value, String description) {
8 | this.value = value;
9 | this.description = description;
10 | }
11 |
12 | public void setValue(String value) {
13 | this.value = value;
14 | }
15 |
16 | public String getValue() {
17 | return value;
18 | }
19 |
20 | public void setDescription(String description) {
21 | this.description = description;
22 | }
23 |
24 | public String getDescription() {
25 | return description;
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 25
5 | buildToolsVersion "25.0.2"
6 |
7 | defaultConfig {
8 | applicationId "net.sourceforge.bochs"
9 | minSdkVersion 16
10 | targetSdkVersion 25
11 | versionCode 26900
12 | versionName "2.6.9"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(dir: 'libs', include: ['*.jar'])
24 | compile 'com.android.support:support-v4:25.2.0'
25 |
26 | compile project(':bochsApp')
27 | }
28 |
--------------------------------------------------------------------------------
/app/src/main/java/net/sourceforge/bochs/entity/EthernetCard.java:
--------------------------------------------------------------------------------
1 | package net.sourceforge.bochs.entity;
2 |
3 | public class EthernetCard {
4 | private String value;
5 | private String description;
6 |
7 | public EthernetCard(String value, String description) {
8 | this.value = value;
9 | this.description = description;
10 | }
11 |
12 | public void setValue(String value) {
13 | this.value = value;
14 | }
15 |
16 | public String getValue() {
17 | return value;
18 | }
19 |
20 | public void setDescription(String description) {
21 | this.description = description;
22 | }
23 |
24 | public String getDescription() {
25 | return description;
26 | }
27 |
28 | }
29 |
--------------------------------------------------------------------------------
/bochsApp/build.gradle:
--------------------------------------------------------------------------------
1 | buildscript {
2 | repositories {
3 | jcenter()
4 | }
5 | dependencies {
6 | classpath 'com.android.tools.build:gradle:2.3.0'
7 | }
8 | }
9 |
10 | apply plugin: 'com.android.library'
11 |
12 | android {
13 | sourceSets {
14 | main {
15 | manifest.srcFile 'AndroidManifest.xml'
16 | java.srcDirs = ['src']
17 | res.srcDirs = ['res']
18 | }
19 | }
20 |
21 | compileSdkVersion 25
22 | buildToolsVersion "25.0.2"
23 |
24 | lintOptions {
25 | abortOnError false
26 | }
27 |
28 | defaultConfig {
29 | minSdkVersion 14
30 | targetSdkVersion 25
31 | versionCode 1
32 | versionName "1.0"
33 | }
34 | }
--------------------------------------------------------------------------------
/.idea/libraries/support_annotations_25_1_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in C:\tools\adt-bundle-windows-x86_64-20131030\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/main/java/net/sourceforge/bochs/entity/CpuModel.java:
--------------------------------------------------------------------------------
1 | package net.sourceforge.bochs.entity;
2 |
3 | public class CpuModel {
4 | private String value;
5 | private String description;
6 | private String reqFeat;
7 |
8 | public CpuModel(String value, String description, String reqFeat) {
9 | this.value = value;
10 | this.description = description;
11 | this.reqFeat = reqFeat;
12 | }
13 |
14 | public void setReqFeat(String reqFeat) {
15 | this.reqFeat = reqFeat;
16 | }
17 |
18 | public String getReqFeat() {
19 | return reqFeat;
20 | }
21 |
22 | public void setDescription(String description) {
23 | this.description = description;
24 | }
25 |
26 | public String getDescription() {
27 | return description;
28 | }
29 |
30 | public void setValue(String value) {
31 | this.value = value;
32 | }
33 |
34 | public String getValue() {
35 | return value;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/.idea/libraries/support_compat_25_1_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/libraries/support_core_ui_25_1_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/libraries/support_fragment_25_1_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/libraries/support_core_utils_25_1_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/.idea/libraries/support_media_compat_25_1_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/java/net/sourceforge/bochs/adapter/TabsPagerAdapter.java:
--------------------------------------------------------------------------------
1 | package net.sourceforge.bochs.adapter;
2 |
3 | import android.support.v4.app.Fragment;
4 | import android.support.v4.app.FragmentManager;
5 | import android.support.v4.app.FragmentPagerAdapter;
6 |
7 | import net.sourceforge.bochs.HardwareTabFragment;
8 | import net.sourceforge.bochs.MiscTabFragment;
9 | import net.sourceforge.bochs.StorageTabFragment;
10 |
11 | public class TabsPagerAdapter extends FragmentPagerAdapter {
12 |
13 | public TabsPagerAdapter(FragmentManager fm) {
14 | super(fm);
15 | }
16 |
17 | @Override
18 | public Fragment getItem(int index) {
19 |
20 | switch (index) {
21 | case 0:
22 | // Storage tab fragment activity
23 | return new StorageTabFragment();
24 | case 1:
25 | // Hardware tab fragment activity
26 | return new HardwareTabFragment();
27 | case 2:
28 | // Misc tab fragment activity
29 | return new MiscTabFragment();
30 | }
31 |
32 | return null;
33 | }
34 |
35 | @Override
36 | public int getCount() {
37 | // get item count - equal to number of tabs
38 | return 3;
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/res/values-zh-rCN/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Bochs
5 | 存储
6 | 配置
7 | 其它
8 | 发生错误, 配置文件无法保存
9 | 配置文件保存成功
10 | 找不到配置文件
11 | 配置文件加载完毕
12 | 下载磁盘映像
13 | 选择
14 | 无
15 | 软盘A
16 | 软盘B
17 | ata0-master
18 | ata0-slave
19 | ata1-master
20 | ata1-slave
21 | 共享文件夹
22 | 启动
23 | CPU类型:
24 | 描述
25 | 芯片组:
26 | i430fx
27 | i440fx
28 | 内存:
29 | 值
30 | VGA显示卡:
31 | 声卡:
32 | 网卡:
33 | PCI:
34 | 插槽1:
35 | 插槽2:
36 | 插槽3:
37 | 插槽4:
38 | 插槽5:
39 | rom 镜像
40 | vga rom 镜像
41 | 时钟:
42 | 同步:
43 | VGA刷新频率:
44 | 全屏模式
45 | 扬声器
46 |
47 |
48 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Bochs
5 | Storage
6 | Hardware
7 | Misc
8 | Error, config not saved
9 | config saved
10 | config not found
11 | config loaded
12 | Download disk images
13 | select
14 | none
15 | Floppy A
16 | Floppy B
17 | ata0-master
18 | ata0-slave
19 | ata1-master
20 | ata1-slave
21 | vfat
22 | Boot
23 | CPU Model:
24 | description
25 | Chipset:
26 | i430fx
27 | i440fx
28 | Memory:
29 | value
30 | VGA Card:
31 | Sound Card:
32 | Ethernet Card:
33 | PCI:
34 | Slot1:
35 | Slot2:
36 | Slot3:
37 | Slot4:
38 | Slot5:
39 | rom image
40 | vga rom image
41 | Clock:
42 | sync:
43 | VGA update freq:
44 | Full screen
45 | Speaker
46 |
47 |
48 |
--------------------------------------------------------------------------------
/bochsApp/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
13 |
17 |
18 |
19 |
24 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
5 |
13 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/app/src/main/res/raw/data_json:
--------------------------------------------------------------------------------
1 | {"cpulist":[
2 | {
3 | "value":"bx_generic",
4 | "description":"Default Bochs CPU configured with CPUID option",
5 | "required":"cpu level 5"
6 | },
7 |
8 | {
9 | "value":"pentium",
10 | "description":"Intel Pentium (P54C)",
11 | "required":"cpu level 5"
12 | },
13 |
14 | {
15 | "value":"pentium_mmx",
16 | "description":"Intel Pentium MMX",
17 | "required":"cpu level 5"
18 | },
19 |
20 | {
21 | "value":"amd_k6_2_chomper",
22 | "description":"AMD-K6(tm) 3D processor (Chomper)",
23 | "required":"cpu level 5"
24 | },
25 |
26 | {
27 | "value":"p2_klamath",
28 | "description":"Intel Pentium II (Klamath)",
29 | "required":"cpu level 6"
30 | },
31 |
32 | {
33 | "value":"p3_katmai",
34 | "description":"Intel Pentium III (Katmai)",
35 | "required":"cpu level 6"
36 | },
37 |
38 | {
39 | "value":"p4_willamette",
40 | "description":"Intel(R) Pentium(R) 4 (Willamette)",
41 | "required":"cpu level 6"
42 | },
43 |
44 | {
45 | "value":"core_duo_t2400_yonah",
46 | "description":"Intel(R) Core(TM) Duo CPU T2400 (Yonah)",
47 | "required":"cpu level 6"
48 | },
49 |
50 | {
51 | "value":"atom_n270",
52 | "description":"Intel(R) Atom(TM) CPU N270",
53 | "required":"cpu level 6"
54 | },
55 |
56 | {
57 | "value":"p4_prescott_celeron_336",
58 | "description":"Intel(R) Celeron(R) 336 (Prescott)",
59 | "required":"cpu level 6, x86-64"
60 | },
61 |
62 | {
63 | "value":"athlon64_clawhammer",
64 | "description":"AMD Athlon(tm) 64 Processor 2800+ (Clawhammer)",
65 | "required":"cpu level 6, x86-64"
66 | },
67 |
68 | {
69 | "value":"athlon64_venice",
70 | "description":"AMD Athlon(tm) 64 Processor 3000+ (Venice)",
71 | "required":"cpu level 6, x86-64"
72 | },
73 |
74 | {
75 | "value":"turion64_tyler",
76 | "description":"AMD Turion(tm) 64 X2 Mobile TL-60 (Tyler)",
77 | "required":"cpu level 6, x86-64"
78 | },
79 |
80 | {
81 | "value":"phenom_8650_toliman",
82 | "description":"AMD Phenom X3 8650 (Toliman)",
83 | "required":"cpu level 6, x86-64"
84 | },
85 |
86 | {
87 | "value":"core2_penryn_t9600",
88 | "description":"Intel Mobile Core 2 Duo T9600 (Penryn)",
89 | "required":"cpu level 6, x86-64"
90 | },
91 |
92 | {
93 | "value":"corei5_lynnfield_750",
94 | "description":"Intel(R) Core(TM) i5 750 (Lynnfield)",
95 | "required":"cpu level 6, x86-64"
96 | },
97 |
98 | {
99 | "value":"corei5_arrandale_m520",
100 | "description":"Intel(R) Core(TM) i5 M 520 (Arrandale)",
101 | "required":"cpu level 6, x86-64"
102 | },
103 |
104 | {
105 | "value":"corei7_sandy_bridge_2600k",
106 | "description":"Intel(R) Core(TM) i7-2600K (Sandy Bridge)",
107 | "required":"cpu level 6, x86-64, avx"
108 | },
109 |
110 | {
111 | "value":"zambezi",
112 | "description":"AMD FX(tm)-4100 Quad-Core Processor (Zambezi)",
113 | "required":"cpu level 6, x86-64, avx"
114 | },
115 |
116 | {
117 | "value":"trinity_apu",
118 | "description":"AMD A8-5600K APU (Trinity)",
119 | "required":"cpu level 6, x86-64, avx"
120 | },
121 |
122 | {
123 | "value":"ryzen",
124 | "description":"AMD Ryzen 7 1700",
125 | "required":"cpu level 6, x86-64, avx"
126 | },
127 |
128 | {
129 | "value":"corei7_ivy_bridge_3770k",
130 | "description":"Intel(R) Core(TM) i7-3770K CPU (Ivy Bridge)",
131 | "required":"cpu level 6, x86-64, avx"
132 | },
133 |
134 | {
135 | "value":"corei7_haswell_4770",
136 | "description":"Intel(R) Core(TM) i7-4770 CPU (Haswell)",
137 | "required":"cpu level 6, x86-64, avx"
138 | },
139 |
140 | {
141 | "value":"broadwell_ult",
142 | "description":"Intel(R) Processor 5Y70 CPU (Broadwell)",
143 | "required":"cpu level 6, x86-64, avx"
144 | }
145 |
146 | ],
147 |
148 | "vgalist":[
149 | {
150 | "value":"vbe",
151 | "description":"Bochs VBE (ISA)"
152 | },
153 |
154 | {
155 | "value":"pcivga",
156 | "description":"Bochs VBE (PCI)"
157 | },
158 |
159 | {
160 | "value":"cirrus_5430",
161 | "description":"Cirrus Logic CL-GD5430 (ISA)"
162 | },
163 |
164 | {
165 | "value":"cirrus_5446",
166 | "description":"Cirrus Logic CL-GD5446 (PCI)"
167 | }
168 |
169 | ],
170 |
171 | "soundlist":[
172 | {
173 | "value":"none",
174 | "description":""
175 | },
176 |
177 | {
178 | "value":"sb16",
179 | "description":"Creative Sound Blaster 16 (ISA)"
180 | },
181 |
182 | {
183 | "value":"es1370",
184 | "description":"Ensoniq ES1370 (PCI)"
185 | }
186 |
187 | ],
188 |
189 | "ethernetlist":[
190 | {
191 | "value":"none",
192 | "description":""
193 | },
194 |
195 | {
196 | "value":"ne2k",
197 | "description":"Novell NE2000 (ISA)"
198 | },
199 |
200 | {
201 | "value":"rtl8029",
202 | "description":"Realtek RTL8029 (PCI)"
203 | },
204 |
205 | {
206 | "value":"e1000",
207 | "description":"Intel 82540EM (PCI)"
208 | }
209 |
210 | ]}
211 |
--------------------------------------------------------------------------------
/app/src/main/java/net/sourceforge/bochs/FileChooser.java:
--------------------------------------------------------------------------------
1 | package net.sourceforge.bochs;
2 |
3 | import android.app.Activity;
4 | import android.app.Dialog;
5 | import android.os.Environment;
6 | import android.util.Log;
7 | import android.view.View;
8 | import android.view.ViewGroup;
9 | import android.view.WindowManager.LayoutParams;
10 | import android.widget.AdapterView;
11 | import android.widget.ArrayAdapter;
12 | import android.widget.ListView;
13 | import android.widget.TextView;
14 |
15 | import java.io.File;
16 | import java.io.FileFilter;
17 | import java.util.Arrays;
18 |
19 | public class FileChooser {
20 | private static final String PARENT_DIR = "..";
21 |
22 | private final Activity activity;
23 | private ListView list;
24 | private Dialog dialog;
25 | private File currentPath;
26 |
27 | // filter on file extension
28 | private String extension[] = null;
29 |
30 | public void setExtension(String... extension) {
31 | this.extension = (extension == null) ? null : extension;
32 | }
33 |
34 | // file selection event handling
35 | public interface FileSelectedListener {
36 | void fileSelected(File file);
37 | }
38 |
39 | public FileChooser setFileListener(FileSelectedListener fileListener) {
40 | this.fileListener = fileListener;
41 | return this;
42 | }
43 |
44 | private FileSelectedListener fileListener;
45 |
46 | public FileChooser(Activity activity, String path, String... extension) {
47 | this.activity = activity;
48 | File selectedPath = null;
49 | if (path != null)
50 | selectedPath = new File(path);
51 | this.extension = (extension == null) ? null : extension;
52 | dialog = new Dialog(activity);
53 | list = new ListView(activity);
54 | list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
55 | @Override
56 | public void onItemClick(AdapterView> parent, View view, int which, long id) {
57 | String fileChosen = (String) list.getItemAtPosition(which);
58 | File chosenFile = getChosenFile(fileChosen);
59 | if (chosenFile.isDirectory()) {
60 | refresh(chosenFile);
61 | } else {
62 | if (fileListener != null) {
63 | fileListener.fileSelected(chosenFile);
64 | }
65 | dialog.dismiss();
66 | }
67 | }
68 | });
69 | dialog.setContentView(list);
70 | dialog.getWindow().setLayout(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
71 | if (selectedPath == null)
72 | selectedPath = Environment.getExternalStorageDirectory();
73 | refresh(selectedPath);
74 | }
75 |
76 | public void showDialog() {
77 | dialog.show();
78 | }
79 |
80 |
81 | /**
82 | * Sort, filter and display the files for the given path.
83 | */
84 | private void refresh(File path) {
85 | this.currentPath = path;
86 | if (path.exists()) {
87 | File[] dirs = path.listFiles(new FileFilter() {
88 | @Override
89 | public boolean accept(File file) {
90 | return (file.isDirectory() && file.canRead());
91 | }
92 | });
93 | File[] files = path.listFiles(new FileFilter() {
94 | @Override
95 | public boolean accept(File file) {
96 | if (!file.isDirectory()) {
97 | if (!file.canRead()) {
98 | return false;
99 | } else if (extension == null) {
100 | return true;
101 | } else {
102 | boolean result = false;
103 | for (int i = 0; i < extension.length; i++) {
104 | if (file.getName().toLowerCase().endsWith(extension[i].toLowerCase()))
105 | result = true;
106 | }
107 | return result;
108 | }
109 | } else {
110 | return false;
111 | }
112 | }
113 | });
114 |
115 | // convert to an array
116 | int i = 0;
117 | String[] fileList;
118 | if (path.getParentFile() == null) {
119 | fileList = new String[dirs.length + files.length];
120 | } else {
121 | fileList = new String[dirs.length + files.length + 1];
122 | fileList[i++] = PARENT_DIR;
123 | }
124 | Arrays.sort(dirs);
125 | Arrays.sort(files);
126 | for (File dir : dirs) {
127 | fileList[i++] = dir.getName();
128 | }
129 | for (File file : files) {
130 | fileList[i++] = file.getName();
131 | }
132 |
133 | // refresh the user interface
134 | dialog.setTitle(currentPath.getPath());
135 | ArrayAdapter adapter = new ArrayAdapter(activity,
136 | android.R.layout.simple_list_item_1, fileList) {
137 | @Override
138 | public View getView(int pos, View view, ViewGroup parent) {
139 | view = super.getView(pos, view, parent);
140 | ((TextView) view).setSingleLine(true);
141 | return view;
142 | }
143 | };
144 | list.setAdapter(adapter);
145 | }
146 | }
147 |
148 |
149 | /**
150 | * Convert a relative filename into an actual File object.
151 | */
152 | private File getChosenFile(String fileChosen) {
153 | if (fileChosen.equals(PARENT_DIR)) {
154 | return currentPath.getParentFile();
155 | } else {
156 | return new File(currentPath, fileChosen);
157 | }
158 | }
159 | }
160 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
22 |
23 |
29 |
30 |
39 |
40 |
41 |
42 |
49 |
50 |
56 |
57 |
64 |
65 |
66 |
67 |
74 |
75 |
79 |
80 |
85 |
86 |
92 |
93 |
98 |
99 |
100 |
101 |
102 |
103 |
111 |
112 |
116 |
117 |
122 |
123 |
128 |
129 |
130 |
131 |
137 |
138 |
144 |
145 |
146 |
147 |
148 |
149 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-land/fragment_misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
22 |
23 |
29 |
30 |
39 |
40 |
41 |
42 |
49 |
50 |
56 |
57 |
64 |
65 |
66 |
67 |
73 |
74 |
80 |
81 |
85 |
86 |
91 |
92 |
98 |
99 |
104 |
105 |
106 |
107 |
108 |
109 |
117 |
118 |
122 |
123 |
128 |
129 |
134 |
135 |
136 |
137 |
138 |
139 |
145 |
146 |
152 |
153 |
154 |
155 |
156 |
157 |
--------------------------------------------------------------------------------
/app/src/main/java/net/sourceforge/bochs/MiscTabFragment.java:
--------------------------------------------------------------------------------
1 | package net.sourceforge.bochs;
2 |
3 | import android.os.Bundle;
4 | import android.os.Environment;
5 | import android.support.v4.app.Fragment;
6 | import android.util.Log;
7 | import android.view.LayoutInflater;
8 | import android.view.View;
9 | import android.view.View.OnClickListener;
10 | import android.view.ViewGroup;
11 | import android.widget.AdapterView;
12 | import android.widget.AdapterView.OnItemSelectedListener;
13 | import android.widget.ArrayAdapter;
14 | import android.widget.Button;
15 | import android.widget.CheckBox;
16 | import android.widget.CompoundButton;
17 | import android.widget.SeekBar;
18 | import android.widget.SeekBar.OnSeekBarChangeListener;
19 | import android.widget.Spinner;
20 | import android.widget.SpinnerAdapter;
21 | import android.widget.TextView;
22 |
23 | import java.io.File;
24 | import java.util.Arrays;
25 | import java.util.List;
26 |
27 | public class MiscTabFragment extends Fragment {
28 | private TextView tvRomImage;
29 | private TextView tvVgaRomImage;
30 | private CheckBox cbFullscreen;
31 | private SeekBar sbVgaUpdateFreq;
32 | private TextView tvVgaUpdateFreq;
33 | private CheckBox cbSpeaker;
34 |
35 | private enum Requestor {ROM, VGAROM}
36 |
37 | @Override
38 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
39 | Bundle savedInstanceState) {
40 |
41 | View rootView = inflater.inflate(R.layout.fragment_misc, container, false);
42 | setupView(rootView);
43 |
44 | return rootView;
45 | }
46 |
47 | private void setupView(View rootView) {
48 | final List syncList = Arrays.asList("none", "slowdown", "realtime", "both");
49 | final int minValueVgaUpdateFreq = 5;
50 | Spinner spClockSync = (Spinner) rootView.findViewById(R.id.miscSpinnerClockSync);
51 | Button btRomImage = (Button) rootView.findViewById(R.id.miscButtonRomImage);
52 | Button btVgaRomImage = (Button) rootView.findViewById(R.id.miscButtonVgaRomImage);
53 | tvRomImage = (TextView) rootView.findViewById(R.id.miscTextViewRomImage);
54 | tvVgaRomImage = (TextView) rootView.findViewById(R.id.miscTextViewVgaRomImage);
55 | cbFullscreen = (CheckBox) rootView.findViewById(R.id.miscCheckBoxFullscreen);
56 | sbVgaUpdateFreq = (SeekBar) rootView.findViewById(R.id.miscSeekBarVgaUpdateFreq);
57 | tvVgaUpdateFreq = (TextView) rootView.findViewById(R.id.miscTextViewVgaUpdateFreq);
58 | cbSpeaker = (CheckBox) rootView.findViewById(R.id.miscCheckBoxSpeaker);
59 | SpinnerAdapter syncAdapter = new ArrayAdapter(getActivity(), R.layout.spinner_row, syncList);
60 | spClockSync.setAdapter(syncAdapter);
61 | tvRomImage.setText(MainActivity.getFileName(Config.romImage));
62 | tvVgaRomImage.setText(MainActivity.getFileName(Config.vgaRomImage));
63 | cbFullscreen.setChecked(Config.fullscreen);
64 | cbSpeaker.setChecked(Config.useSpeaker);
65 | spClockSync.setSelection(syncList.indexOf(Config.clockSync));
66 | sbVgaUpdateFreq.setProgress(Config.vgaUpdateFreq - minValueVgaUpdateFreq);
67 | tvVgaUpdateFreq.setText(String.valueOf(Config.vgaUpdateFreq));
68 |
69 | cbFullscreen.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
70 |
71 | @Override
72 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
73 | Config.fullscreen = cbFullscreen.isChecked();
74 | }
75 | }
76 | );
77 |
78 | cbSpeaker.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
79 |
80 | @Override
81 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
82 | Config.useSpeaker = cbSpeaker.isChecked();
83 | }
84 | }
85 | );
86 |
87 | spClockSync.setOnItemSelectedListener(new OnItemSelectedListener() {
88 |
89 | @Override
90 | public void onItemSelected(AdapterView> p1, View p2, int p3, long p4) {
91 | Config.clockSync = syncList.get(p3);
92 | }
93 |
94 | @Override
95 | public void onNothingSelected(AdapterView> p1) {
96 | }
97 | });
98 |
99 | sbVgaUpdateFreq.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
100 |
101 | @Override
102 | public void onProgressChanged(SeekBar p1, int p2, boolean p3) {
103 | tvVgaUpdateFreq.setText(String.valueOf(minValueVgaUpdateFreq + sbVgaUpdateFreq.getProgress()));
104 | Config.vgaUpdateFreq = minValueVgaUpdateFreq + sbVgaUpdateFreq.getProgress();
105 | }
106 |
107 | @Override
108 | public void onStartTrackingTouch(SeekBar p1) {
109 | }
110 |
111 | @Override
112 | public void onStopTrackingTouch(SeekBar p1) {
113 | }
114 | });
115 |
116 | OnClickListener miscOnClick = new OnClickListener() {
117 |
118 | @Override
119 | public void onClick(View p1) {
120 | switch (p1.getId()) {
121 | case R.id.miscButtonRomImage:
122 | fileSelection(Requestor.ROM);
123 | break;
124 | case R.id.miscButtonVgaRomImage:
125 | fileSelection(Requestor.VGAROM);
126 | break;
127 | }
128 | }
129 | };
130 |
131 | btRomImage.setOnClickListener(miscOnClick);
132 | btVgaRomImage.setOnClickListener(miscOnClick);
133 | }
134 |
135 | private void fileSelection(final Requestor num) {
136 | String appPath = Environment.getExternalStorageDirectory().getAbsolutePath() +
137 | "/Android/data/" + getActivity().getPackageName() + "/files/";
138 | FileChooser filechooser = new FileChooser(getActivity(), appPath, null);
139 | filechooser.setFileListener(new FileChooser.FileSelectedListener() {
140 | @Override
141 | public void fileSelected(final File file) {
142 | String filename = file.getAbsolutePath();
143 | Log.d("File", filename);
144 | switch (num) {
145 | case ROM:
146 | tvRomImage.setText(file.getName());
147 | Config.romImage = filename;
148 | break;
149 | case VGAROM:
150 | tvVgaRomImage.setText(file.getName());
151 | Config.vgaRomImage = filename;
152 | break;
153 | }
154 |
155 | }
156 | });
157 | filechooser.showDialog();
158 | }
159 |
160 | }
161 |
--------------------------------------------------------------------------------
/app/app.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | generateDebugSources
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
--------------------------------------------------------------------------------
/app/src/main/java/net/sourceforge/bochs/MainActivity.java:
--------------------------------------------------------------------------------
1 | package net.sourceforge.bochs;
2 |
3 | import android.Manifest;
4 | import android.app.ActionBar;
5 | import android.app.ActionBar.Tab;
6 | import android.app.AlertDialog;
7 | import android.app.DownloadManager;
8 | import android.app.FragmentTransaction;
9 | import android.content.Context;
10 | import android.content.DialogInterface;
11 | import android.content.Intent;
12 | import android.content.SharedPreferences;
13 | import android.content.pm.PackageManager;
14 | import android.net.Uri;
15 | import android.os.Bundle;
16 | import android.os.Environment;
17 | import android.support.v4.app.ActivityCompat;
18 | import android.support.v4.app.FragmentActivity;
19 | import android.support.v4.view.ViewPager;
20 | import android.util.Log;
21 | import android.view.Menu;
22 | import android.view.MenuInflater;
23 | import android.view.MenuItem;
24 | import android.widget.Toast;
25 |
26 | import net.sourceforge.bochs.adapter.TabsPagerAdapter;
27 |
28 | import java.io.File;
29 | import java.io.FileNotFoundException;
30 | import java.io.IOException;
31 |
32 | public class MainActivity extends FragmentActivity implements ActionBar.TabListener {
33 |
34 | private String appPath;
35 | private String configPath;
36 | private ViewPager viewPager;
37 | private ActionBar actionBar;
38 | private SharedPreferences sPref;
39 | final String SAVED_PATH = "saved_path";
40 | private final int REQUEST_EXTERNAL_STORAGE = 1;
41 |
42 | @Override
43 | protected void onCreate(Bundle savedInstanceState) {
44 | super.onCreate(savedInstanceState);
45 | setContentView(R.layout.main);
46 |
47 | appPath = Environment.getExternalStorageDirectory().getAbsolutePath() +
48 | "/Android/data/" + getPackageName() + "/files/";
49 | configPath = appPath + "bochsrc.txt";
50 |
51 | if (!Config.configLoaded)
52 | Config.setDefaulValues();
53 |
54 | verifyStoragePermissions();
55 | setupTabs();
56 | }
57 |
58 | @SuppressWarnings("deprecation")
59 | private void setupTabs() {
60 | // Initilization
61 | viewPager = (ViewPager) findViewById(R.id.pager);
62 | actionBar = getActionBar();
63 | TabsPagerAdapter mAdapter = new TabsPagerAdapter(getSupportFragmentManager());
64 |
65 | viewPager.setAdapter(mAdapter);
66 | actionBar.setHomeButtonEnabled(false);
67 | actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
68 |
69 | // Tab titles
70 | String[] tabs = {getString(R.string.storage), getString(R.string.hardware), getString(R.string.misc)};
71 |
72 | // Adding Tabs
73 | for (String tab_name : tabs) {
74 | actionBar.addTab(actionBar.newTab().setText(tab_name)
75 | .setTabListener(this));
76 | }
77 |
78 | /**
79 | * on swiping the viewpager make respective tab selected
80 | * */
81 | viewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
82 |
83 | @Override
84 | public void onPageSelected(int position) {
85 | // on changing the page
86 | // make respected tab selected
87 | actionBar.setSelectedNavigationItem(position);
88 | }
89 |
90 | @Override
91 | public void onPageScrolled(int arg0, float arg1, int arg2) {
92 | }
93 |
94 | @Override
95 | public void onPageScrollStateChanged(int arg0) {
96 | }
97 | });
98 |
99 | }
100 |
101 | @Override
102 | public boolean onCreateOptionsMenu(Menu menu) {
103 | MenuInflater inflater = getMenuInflater();
104 | inflater.inflate(R.menu.menu, menu);
105 | return true;
106 | }
107 |
108 | @Override
109 | public boolean onOptionsItemSelected(MenuItem item) {
110 | int id = item.getItemId();
111 | switch (id) {
112 | case R.id.start:
113 | save();
114 | break;
115 | case R.id.download:
116 | downloadImages();
117 | break;
118 | }
119 | return super.onOptionsItemSelected(item);
120 | }
121 |
122 | @Override
123 | public void onTabReselected(Tab tab, FragmentTransaction ft) {
124 | }
125 |
126 | @Override
127 | public void onTabSelected(Tab tab, FragmentTransaction ft) {
128 | // on tab selected
129 | // show respected fragment view
130 | viewPager.setCurrentItem(tab.getPosition());
131 | }
132 |
133 | @Override
134 | public void onTabUnselected(Tab tab, FragmentTransaction ft) {
135 | }
136 |
137 | static String getFileName(String path) {
138 | String result;
139 | if (path.contains("/"))
140 | result = path.substring(path.lastIndexOf("/") + 1, path.length());
141 | else
142 | result = path;
143 | return result;
144 | }
145 |
146 | private void save() {
147 | try {
148 | Config.writeConfig(configPath);
149 | } catch (IOException e) {
150 | Toast.makeText(MainActivity.this, getString(R.string.config_not_saved), Toast.LENGTH_SHORT).show();
151 | }
152 | Toast.makeText(MainActivity.this, getString(R.string.config_saved), Toast.LENGTH_SHORT).show();
153 |
154 | // run bochs app
155 | //ComponentName cn = new ComponentName("net.sourceforge.bochs", "net.sourceforge.bochs.MainActivity");
156 | Intent intent = new Intent(this, SDLActivity.class);
157 | //intent.setComponent(cn);
158 | startActivity(intent);
159 | }
160 |
161 | private void checkConfig() {
162 | if (!Config.configLoaded) {
163 | Config.configLoaded = true;
164 | try {
165 | Config.readConfig(configPath);
166 | } catch (FileNotFoundException e) {
167 | Toast.makeText(MainActivity.this, getString(R.string.config_not_found), Toast.LENGTH_SHORT).show();
168 | return;
169 | }
170 | Toast.makeText(MainActivity.this, getString(R.string.config_loaded), Toast.LENGTH_SHORT).show();
171 | }
172 | }
173 |
174 | private boolean createDirIfNotExists() {
175 | boolean ret = true;
176 |
177 | File file = new File(appPath);
178 | if (!file.exists()) {
179 | if (!file.mkdirs()) {
180 | ret = false;
181 | }
182 | }
183 | return ret;
184 | }
185 |
186 | @Override
187 | public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
188 | switch (requestCode) {
189 | case REQUEST_EXTERNAL_STORAGE:
190 | if (grantResults.length != 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
191 | // Permission Granted
192 | createDirIfNotExists();
193 | checkConfig();
194 | } else {
195 | Toast.makeText(this, "Permission Denied", Toast.LENGTH_LONG).show();
196 | }
197 | break;
198 | default:
199 | super.onRequestPermissionsResult(requestCode, permissions, grantResults);
200 | }
201 | }
202 |
203 | public void verifyStoragePermissions() {
204 | if (ActivityCompat.checkSelfPermission(this,
205 | Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
206 |
207 | String[] PERMISSIONS_STORAGE = new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
208 | Manifest.permission.WRITE_EXTERNAL_STORAGE};
209 |
210 | ActivityCompat.requestPermissions(
211 | this,
212 | PERMISSIONS_STORAGE,
213 | REQUEST_EXTERNAL_STORAGE
214 | );
215 | return;
216 | }
217 | createDirIfNotExists();
218 | checkConfig();
219 | }
220 |
221 | private void downloadImages() {
222 | final String urls[] = {
223 | "https://sourceforge.net/projects/libsdl-android/files/Bochs/mulinux13r2.img/download",
224 | "https://sourceforge.net/projects/libsdl-android/files/Bochs/FreeDos.vdi/download",
225 | "https://sourceforge.net/projects/libsdl-android/files/Bochs/tinycore-2.1-x86.vdi/download",
226 | "https://sourceforge.net/projects/libsdl-android/files/Bochs/LucidPuppy-520.vdi/download",
227 | };
228 | final String names[] = {
229 | "muLinux - 34 Mb",
230 | "FreeDOS - 114 Mb",
231 | "Tiny Core Linux - 123 Mb",
232 | "Puppy Linux - 690 Mb",
233 | };
234 |
235 | new AlertDialog.Builder(this)
236 | .setTitle(getString(R.string.download_disk_images))
237 | .setItems(names, new DialogInterface.OnClickListener() {
238 | public void onClick(DialogInterface dialog, int i) {
239 | String destination = Uri.parse(urls[i]).getPathSegments()
240 | .get(Uri.parse(urls[i]).getPathSegments().size() - 2);
241 | Log.d("BOCHS", "Downloading image " + urls[i] + " to " + destination);
242 | DownloadManager downloader = (DownloadManager) MainActivity.this
243 | .getSystemService(Context.DOWNLOAD_SERVICE);
244 | DownloadManager.Request request = new DownloadManager.Request(Uri.parse(urls[i]));
245 | request.setTitle(names[i]);
246 | request.setDescription(urls[i]);
247 | request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS,
248 | destination);
249 | downloader.enqueue(request);
250 | dialog.dismiss();
251 | setPathToDownload();
252 | }
253 | })
254 | .setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
255 | public void onClick(DialogInterface dialog, int which) {
256 | dialog.dismiss();
257 | }
258 | })
259 | .create()
260 | .show();
261 | }
262 |
263 | private void setPathToDownload() {
264 | sPref = getPreferences(MODE_PRIVATE);
265 | SharedPreferences.Editor ed = sPref.edit();
266 | ed.putString(SAVED_PATH, Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath());
267 | ed.apply();
268 | }
269 |
270 | }
271 |
--------------------------------------------------------------------------------
/app/src/main/java/net/sourceforge/bochs/DirectoryChooserDialog.java:
--------------------------------------------------------------------------------
1 | package net.sourceforge.bochs;
2 |
3 | import android.app.AlertDialog;
4 | import android.content.Context;
5 | import android.content.DialogInterface;
6 | import android.content.DialogInterface.OnClickListener;
7 | import android.content.DialogInterface.OnKeyListener;
8 | import android.os.Environment;
9 | import android.text.Editable;
10 | import android.view.Gravity;
11 | import android.view.KeyEvent;
12 | import android.view.View;
13 | import android.view.ViewGroup;
14 | import android.view.ViewGroup.LayoutParams;
15 | import android.widget.ArrayAdapter;
16 | import android.widget.Button;
17 | import android.widget.EditText;
18 | import android.widget.LinearLayout;
19 | import android.widget.TextView;
20 | import android.widget.Toast;
21 |
22 | import java.io.File;
23 | import java.io.IOException;
24 | import java.util.ArrayList;
25 | import java.util.Collections;
26 | import java.util.Comparator;
27 | import java.util.List;
28 |
29 | public class DirectoryChooserDialog {
30 | private boolean m_isNewFolderEnabled = true;
31 | private String m_sdcardDirectory = "";
32 | private Context m_context;
33 | private TextView m_titleView;
34 |
35 | private String m_dir = "";
36 | private List m_subdirs = null;
37 | private ChosenDirectoryListener m_chosenDirectoryListener = null;
38 | private ArrayAdapter m_listAdapter = null;
39 |
40 | //////////////////////////////////////////////////////
41 | // Callback interface for selected directory
42 | //////////////////////////////////////////////////////
43 | public interface ChosenDirectoryListener {
44 | public void onChosenDir(String chosenDir);
45 | }
46 |
47 | public DirectoryChooserDialog(Context context, ChosenDirectoryListener chosenDirectoryListener) {
48 | m_context = context;
49 | m_sdcardDirectory = Environment.getExternalStorageDirectory().getAbsolutePath();
50 | m_chosenDirectoryListener = chosenDirectoryListener;
51 |
52 | try {
53 | m_sdcardDirectory = new File(m_sdcardDirectory).getCanonicalPath();
54 | } catch (IOException ioe) {
55 | }
56 | }
57 |
58 | ///////////////////////////////////////////////////////////////////////
59 | // setNewFolderEnabled() - enable/disable new folder button
60 | ///////////////////////////////////////////////////////////////////////
61 |
62 | public void setNewFolderEnabled(boolean isNewFolderEnabled) {
63 | m_isNewFolderEnabled = isNewFolderEnabled;
64 | }
65 |
66 | public boolean getNewFolderEnabled() {
67 | return m_isNewFolderEnabled;
68 | }
69 |
70 | ///////////////////////////////////////////////////////////////////////
71 | // chooseDirectory() - load directory chooser dialog for initial
72 | // default sdcard directory
73 | ///////////////////////////////////////////////////////////////////////
74 |
75 | public void chooseDirectory() {
76 | // Initial directory is sdcard directory
77 | chooseDirectory(m_sdcardDirectory);
78 | }
79 |
80 | ////////////////////////////////////////////////////////////////////////////////
81 | // chooseDirectory(String dir) - load directory chooser dialog for initial
82 | // input 'dir' directory
83 | ////////////////////////////////////////////////////////////////////////////////
84 |
85 | public void chooseDirectory(String dir) {
86 | File dirFile = new File(dir);
87 | if (!dirFile.exists() || !dirFile.isDirectory()) {
88 | dir = m_sdcardDirectory;
89 | }
90 |
91 | try {
92 | dir = new File(dir).getCanonicalPath();
93 | } catch (IOException ioe) {
94 | return;
95 | }
96 |
97 | m_dir = dir;
98 | m_subdirs = getDirectories(dir);
99 |
100 | class DirectoryOnClickListener implements DialogInterface.OnClickListener {
101 | public void onClick(DialogInterface dialog, int item) {
102 | // Navigate into the sub-directory
103 | m_dir += "/" + ((AlertDialog) dialog).getListView().getAdapter().getItem(item);
104 | updateDirectory();
105 | }
106 | }
107 |
108 | AlertDialog.Builder dialogBuilder =
109 | createDirectoryChooserDialog(dir, m_subdirs, new DirectoryOnClickListener());
110 |
111 | dialogBuilder.setPositiveButton("OK", new OnClickListener() {
112 | @Override
113 | public void onClick(DialogInterface dialog, int which) {
114 | // Current directory chosen
115 | if (m_chosenDirectoryListener != null) {
116 | // Call registered listener supplied with the chosen directory
117 | m_chosenDirectoryListener.onChosenDir(m_dir);
118 | }
119 | }
120 | }).setNegativeButton("Cancel", null);
121 |
122 | final AlertDialog dirsDialog = dialogBuilder.create();
123 |
124 | dirsDialog.setOnKeyListener(new OnKeyListener() {
125 | @Override
126 | public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
127 | if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
128 | // Back button pressed
129 | if (m_dir.equals(m_sdcardDirectory)) {
130 | // The very top level directory, do nothing
131 | return false;
132 | } else {
133 | // Navigate back to an upper directory
134 | m_dir = new File(m_dir).getParent();
135 | updateDirectory();
136 | }
137 |
138 | return true;
139 | } else {
140 | return false;
141 | }
142 | }
143 | });
144 |
145 | // Show directory chooser dialog
146 | dirsDialog.show();
147 | }
148 |
149 | private boolean createSubDir(String newDir) {
150 | File newDirFile = new File(newDir);
151 | if (!newDirFile.exists()) {
152 | return newDirFile.mkdir();
153 | }
154 |
155 | return false;
156 | }
157 |
158 | private List getDirectories(String dir) {
159 | List dirs = new ArrayList();
160 |
161 | try {
162 | File dirFile = new File(dir);
163 | if (!dirFile.exists() || !dirFile.isDirectory()) {
164 | return dirs;
165 | }
166 | dirs.add("..");
167 | for (File file : dirFile.listFiles()) {
168 | if (file.isDirectory()) {
169 | dirs.add(file.getName());
170 | }
171 | }
172 | } catch (Exception e) {
173 | }
174 |
175 | Collections.sort(dirs, new Comparator() {
176 | public int compare(String o1, String o2) {
177 | return o1.compareTo(o2);
178 | }
179 | });
180 |
181 | return dirs;
182 | }
183 |
184 | private AlertDialog.Builder createDirectoryChooserDialog(String title, List listItems,
185 | DialogInterface.OnClickListener onClickListener) {
186 | AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(m_context);
187 |
188 | // Create custom view for AlertDialog title containing
189 | // current directory TextView and possible 'New folder' button.
190 | // Current directory TextView allows long directory path to be wrapped to multiple lines.
191 | LinearLayout titleLayout = new LinearLayout(m_context);
192 | titleLayout.setOrientation(LinearLayout.VERTICAL);
193 |
194 | m_titleView = new TextView(m_context);
195 | m_titleView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
196 | m_titleView.setTextAppearance(m_context, android.R.style.TextAppearance_Large);
197 | m_titleView.setTextColor(m_context.getResources().getColor(android.R.color.white));
198 | m_titleView.setGravity(Gravity.CENTER_VERTICAL | Gravity.CENTER_HORIZONTAL);
199 | m_titleView.setText(title);
200 |
201 | Button newDirButton = new Button(m_context);
202 | newDirButton.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
203 | newDirButton.setText("New folder");
204 | newDirButton.setOnClickListener(new View.OnClickListener() {
205 | @Override
206 | public void onClick(View v) {
207 | final EditText input = new EditText(m_context);
208 |
209 | // Show new folder name input dialog
210 | new AlertDialog.Builder(m_context).
211 | setTitle("New folder name").
212 | setView(input).setPositiveButton("OK", new DialogInterface.OnClickListener() {
213 | public void onClick(DialogInterface dialog, int whichButton) {
214 | Editable newDir = input.getText();
215 | String newDirName = newDir.toString();
216 | // Create new directory
217 | if (createSubDir(m_dir + "/" + newDirName)) {
218 | // Navigate into the new directory
219 | m_dir += "/" + newDirName;
220 | updateDirectory();
221 | } else {
222 | Toast.makeText(
223 | m_context, "Failed to create '" + newDirName +
224 | "' folder", Toast.LENGTH_SHORT).show();
225 | }
226 | }
227 | }).setNegativeButton("Cancel", null).show();
228 | }
229 | });
230 |
231 | if (!m_isNewFolderEnabled) {
232 | newDirButton.setVisibility(View.GONE);
233 | }
234 |
235 | titleLayout.addView(m_titleView);
236 | titleLayout.addView(newDirButton);
237 |
238 | dialogBuilder.setCustomTitle(titleLayout);
239 |
240 | m_listAdapter = createListAdapter(listItems);
241 |
242 | dialogBuilder.setSingleChoiceItems(m_listAdapter, -1, onClickListener);
243 | dialogBuilder.setCancelable(false);
244 |
245 | return dialogBuilder;
246 | }
247 |
248 | private void updateDirectory() {
249 | m_subdirs.clear();
250 | m_subdirs.addAll(getDirectories(m_dir));
251 | m_titleView.setText(m_dir);
252 |
253 | m_listAdapter.notifyDataSetChanged();
254 | }
255 |
256 | private ArrayAdapter createListAdapter(List items) {
257 | return new ArrayAdapter(m_context,
258 | android.R.layout.select_dialog_item, android.R.id.text1, items) {
259 | @Override
260 | public View getView(int position, View convertView,
261 | ViewGroup parent) {
262 | View v = super.getView(position, convertView, parent);
263 |
264 | if (v instanceof TextView) {
265 | // Enable list item (directory) text wrapping
266 | TextView tv = (TextView) v;
267 | tv.getLayoutParams().height = LayoutParams.WRAP_CONTENT;
268 | tv.setEllipsize(null);
269 | }
270 | return v;
271 | }
272 | };
273 | }
274 | }
275 |
--------------------------------------------------------------------------------
/app/src/main/java/net/sourceforge/bochs/Config.java:
--------------------------------------------------------------------------------
1 | package net.sourceforge.bochs;
2 |
3 | import java.io.File;
4 | import java.io.FileNotFoundException;
5 | import java.io.FileWriter;
6 | import java.io.IOException;
7 | import java.util.Scanner;
8 |
9 | class Config {
10 | static final String NONE = "none";
11 | static final String DISK = "disk";
12 | static final String CDROM = "cdrom";
13 | static final String FLOPPY = "floppy";
14 | static final String VFAT = "vvfat";
15 | static final int floppyNum = 2;
16 | static final int ataNum = 4;
17 | static boolean useSb16 = false;
18 | static boolean useEs1370 = false;
19 | static boolean useNe2000 = false;
20 | static boolean useRtl8029 = false;
21 | static boolean useE1000 = false;
22 | static boolean useVoodoo = false;
23 | static Boolean floppy[] = new Boolean[floppyNum];
24 | static String floppyImage[] = new String[floppyNum];
25 | static Boolean ata[] = new Boolean[ataNum];
26 | static String ataImage[] = new String[ataNum];
27 | static String ataType[] = new String[ataNum];
28 | static String ataMode[] = new String[ataNum];
29 | static String boot = DISK;
30 |
31 | static String romImage = "BIOS-bochs-latest";
32 | static String vgaRomImage = "VGABIOS-lgpl-latest-cirrus";
33 | static int megs = 32;
34 | static String vgaExtension = "cirrus";
35 | static int vgaUpdateFreq = 15;
36 | static String chipset = "i440fx";
37 | static String[] slot = {"", "", "", "", ""};
38 | static String cpuModel = "bx_generic";
39 | static private String mac = "b0:c4:20:00:00:00";
40 | static private String ethmod = "slirp";
41 | static boolean fullscreen = false;
42 | static boolean useSpeaker = true;
43 | static String clockSync = NONE;
44 |
45 | static boolean configLoaded = false;
46 | static final int FLOPPY_A = 0;
47 | static final int FLOPPY_B = 1;
48 | static final int ATA_0_MASTER = 0;
49 | static final int ATA_0_SLAVE = 1;
50 | static final int ATA_1_MASTER = 2;
51 | static final int ATA_1_SLAVE = 3;
52 |
53 | static void setDefaulValues() {
54 | for (int i=0; i < floppyNum; i++) {
55 | floppy[i] = false;
56 | floppyImage[i] = NONE;
57 | }
58 | for (int i=0; i < ataNum; i++) {
59 | ata[i] = false;
60 | ataImage[i] = NONE;
61 | ataType[i] = DISK;
62 | ataMode[i] = "";
63 | }
64 | }
65 |
66 | static void readConfig(String path) throws FileNotFoundException {
67 | File file = new File(path);
68 | Scanner sc = new Scanner(file).useDelimiter("[\n]");
69 | while (sc.hasNext()) {
70 | String str = sc.next() + "\n";
71 | if (str.startsWith("floppya:")) {
72 | parseFloppyConfig(FLOPPY_A, str);
73 | }
74 |
75 | if (str.startsWith("floppyb:")) {
76 | parseFloppyConfig(FLOPPY_B, str);
77 | }
78 |
79 | if (str.startsWith("ata0-master:")) {
80 | parseAtaConfig(ATA_0_MASTER, str);
81 | }
82 |
83 | if (str.startsWith("ata0-slave:")) {
84 | parseAtaConfig(ATA_0_SLAVE, str);
85 | }
86 |
87 | if (str.startsWith("ata1-master:")) {
88 | parseAtaConfig(ATA_1_MASTER, str);
89 | }
90 |
91 | if (str.startsWith("ata1-slave:")) {
92 | parseAtaConfig(ATA_1_SLAVE, str);
93 | }
94 |
95 | if (str.startsWith("boot:")) {
96 | boot = str.substring(6, str.length() - 1);
97 | }
98 |
99 | if (str.startsWith("romimage:")) {
100 | if (str.contains("file=")) {
101 | String str2 = str.substring(str.indexOf("file="), str.length() - 1);
102 | romImage = str2.contains(",") ?
103 | str2.substring(5, str2.indexOf(",")) : str2.substring(5, str2.length());
104 | }
105 | }
106 |
107 | if (str.startsWith("vgaromimage:")) {
108 | if (str.contains("file=")) {
109 | String str2 = str.substring(str.indexOf("file="), str.length() - 1);
110 | vgaRomImage = str2.contains(",") ?
111 | str2.substring(5, str2.indexOf(",")) : str2.substring(5, str2.length());
112 | }
113 | }
114 |
115 | if (str.startsWith("vga:")) {
116 | if (str.contains("extension=")) {
117 | String str2 = str.substring(str.indexOf("extension="), str.length() - 1);
118 | vgaExtension = str2.contains(",") ?
119 | str2.substring(10, str2.indexOf(",")) : str2.substring(10, str2.length());
120 | }
121 | if (str.contains("update_freq=")) {
122 | String str2 = str.substring(str.indexOf("update_freq="), str.length() - 1);
123 | vgaUpdateFreq = str2.contains(",") ?
124 | Integer.parseInt(str2.substring(12, str2.indexOf(","))) : Integer.parseInt(str2.substring(12, str2.length()));
125 | }
126 | }
127 |
128 | if (str.startsWith("pci:")) {
129 | if (str.contains("chipset=")) {
130 | String str2 = str.substring(str.indexOf("chipset="), str.length() - 1);
131 | chipset = str2.contains(",") ?
132 | str2.substring(8, str2.indexOf(",")) : str2.substring(8, str2.length());
133 | }
134 | if (str.contains("slot1=")) {
135 | String str2 = str.substring(str.indexOf("slot1="), str.length() - 1);
136 | slot[0] = str2.contains(",") ?
137 | str2.substring(6, str2.indexOf(",")) : str2.substring(6, str2.length());
138 | }
139 | if (str.contains("slot2=")) {
140 | String str2 = str.substring(str.indexOf("slot2="), str.length() - 1);
141 | slot[1] = str2.contains(",") ?
142 | str2.substring(6, str2.indexOf(",")) : str2.substring(6, str2.length());
143 | }
144 | if (str.contains("slot3=")) {
145 | String str2 = str.substring(str.indexOf("slot3="), str.length() - 1);
146 | slot[2] = str2.contains(",") ?
147 | str2.substring(6, str2.indexOf(",")) : str2.substring(6, str2.length());
148 | }
149 | if (str.contains("slot4=")) {
150 | String str2 = str.substring(str.indexOf("slot4="), str.length() - 1);
151 | slot[3] = str2.contains(",") ?
152 | str2.substring(6, str2.indexOf(",")) : str2.substring(6, str2.length());
153 | }
154 | if (str.contains("slot5=")) {
155 | String str2 = str.substring(str.indexOf("slot5="), str.length() - 1);
156 | slot[4] = str2.contains(",") ?
157 | str2.substring(6, str2.indexOf(",")) : str2.substring(6, str2.length());
158 | }
159 | }
160 |
161 | if (str.startsWith("cpu:")) {
162 | if (str.contains("model=")) {
163 | String str2 = str.substring(str.indexOf("model="), str.length() - 1);
164 | cpuModel = str2.contains(",") ?
165 | str2.substring(6, str2.indexOf(",")) : str2.substring(6, str2.length());
166 | }
167 | }
168 |
169 | if (str.startsWith("ne2k:")) {
170 | useNe2000 = true;
171 | if (str.contains("mac=")) {
172 | String str2 = str.substring(str.indexOf("mac="), str.length() - 1);
173 | mac = str2.contains(",") ?
174 | str2.substring(4, str2.indexOf(",")) : str2.substring(4, str2.length());
175 | }
176 | if (str.contains("ethmod=")) {
177 | String str2 = str.substring(str.indexOf("ethmod="), str.length() - 1);
178 | ethmod = str2.contains(",") ?
179 | str2.substring(7, str2.indexOf(",")) : str2.substring(7, str2.length());
180 | }
181 | }
182 |
183 | if (str.startsWith("e1000:")) {
184 | useE1000 = true;
185 | if (str.contains("mac=")) {
186 | String str2 = str.substring(str.indexOf("mac="), str.length() - 1);
187 | mac = str2.contains(",") ?
188 | str2.substring(4, str2.indexOf(",")) : str2.substring(4, str2.length());
189 | }
190 | if (str.contains("ethmod=")) {
191 | String str2 = str.substring(str.indexOf("ethmod="), str.length() - 1);
192 | ethmod = str2.contains(",") ?
193 | str2.substring(7, str2.indexOf(",")) : str2.substring(7, str2.length());
194 | }
195 | }
196 |
197 | if (str.startsWith("sb16:")) {
198 | useSb16 = true;
199 | }
200 |
201 | if (str.startsWith("es1370:")) {
202 | useEs1370 = true;
203 | }
204 |
205 | if (str.startsWith("voodoo:")) {
206 | useVoodoo = true;
207 | }
208 |
209 | if (str.startsWith("speaker:")) {
210 | useSpeaker = true;
211 | }
212 |
213 | if (str.startsWith("megs:")) {
214 | megs = Integer.parseInt(str.substring(6, str.length() - 1));
215 | }
216 |
217 | if (str.startsWith("display_library:")) {
218 | if (str.contains("options=")) {
219 | String str2 = str.substring(str.indexOf("options="), str.length() - 1);
220 | fullscreen = str2.contains("fullscreen");
221 | }
222 | }
223 |
224 | if (str.startsWith("clock:")) {
225 | if (str.contains("sync=")) {
226 | String str2 = str.substring(str.indexOf("sync="), str.length() - 1);
227 | clockSync = str2.contains(",") ?
228 | str2.substring(5, str2.indexOf(",")) : str2.substring(5, str2.length());
229 | }
230 | }
231 | }
232 | sc.close();
233 | }
234 |
235 | static private void parseFloppyConfig(int n, String str) {
236 | floppy[n] = true;
237 | if (str.contains("1_44=")) {
238 | String str2 = str.substring(str.indexOf("1_44="), str.length() - 1);
239 | floppyImage[n] = str2.contains(",") ?
240 | str2.substring(5, str2.indexOf(",")) : str2.substring(5, str2.length());
241 | }
242 | if (str.contains("image=")) {
243 | String str2 = str.substring(str.indexOf("image="), str.length() - 1);
244 | floppyImage[n] = str2.contains(",") ?
245 | str2.substring(6, str2.indexOf(",")) : str2.substring(6, str2.length());
246 | }
247 | }
248 |
249 | static private void parseAtaConfig(int n, String str) {
250 | ata[n] = true;
251 | if (str.contains("type=")) {
252 | String str2 = str.substring(str.indexOf("type="), str.length() - 1);
253 | ataType[n] = str2.contains(",") ?
254 | str2.substring(5, str2.indexOf(",")) : str2.substring(5, str2.length());
255 | }
256 | if (str.contains("mode=")) {
257 | String str2 = str.substring(str.indexOf("mode="), str.length() - 1);
258 | ataMode[n] = str2.contains(",") ?
259 | str2.substring(5, str2.indexOf(",")) : str2.substring(5, str2.length());
260 | }
261 | if (str.contains("path=")) {
262 | String str2 = str.substring(str.indexOf("path="), str.length() - 1);
263 | ataImage[n] = str2.contains(",") ?
264 | str2.substring(5, str2.indexOf(",")) : str2.substring(5, str2.length());
265 | ataImage[n] = ataImage[n].replace("\"", "");
266 | }
267 | }
268 |
269 | static void writeConfig(String path) throws IOException {
270 | File file = new File(path);
271 | FileWriter fw = new FileWriter(file);
272 | if (fullscreen)
273 | fw.write("display_library: sdl, options=fullscreen\n");
274 | fw.write("romimage: file=" + romImage + "\n");
275 | fw.write("vgaromimage: file=" + vgaRomImage + "\n");
276 | fw.write("cpu: model=" + cpuModel + "\n");
277 | fw.write("vga: extension=" + vgaExtension + ", update_freq=" + vgaUpdateFreq + "\n");
278 | fw.write("pci: enabled=1, chipset=" + chipset);
279 | for (int i = 0; i < slot.length; i++) {
280 | String label[] = {"slot1", "slot2", "slot3", "slot4", "slot5"};
281 | if (!slot[i].equals("")) {
282 | fw.write(", " + label[i] + "=" + slot[i]);
283 | }
284 | }
285 | fw.write("\n");
286 | if (useRtl8029)
287 | fw.write("ne2k: mac=" + mac + ", ethmod=" + ethmod + ", script=\"\"\n");
288 | else if (useNe2000)
289 | fw.write("ne2k: ioaddr=0x300, irq=10, mac=" + mac + ", ethmod=" + ethmod + ", script=\"\"\n");
290 | if (useE1000)
291 | fw.write("e1000: mac=" + mac + ", ethmod=" + ethmod + ", script=\"\"\n");
292 |
293 | for (int i = 0; i < floppyNum; i++) {
294 | String label[] = {"floppya", "floppyb"};
295 | if (floppy[i]) {
296 | fw.write(label[i]+": image=" + floppyImage[i] + ", status=inserted\n");
297 | }
298 | }
299 |
300 | fw.write("ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14\n");
301 | fw.write("ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15\n");
302 | for (int i = 0; i < ataNum; i++) {
303 | String label[] = {"ata0-master", "ata0-slave", "ata1-master", "ata1-slave"};
304 | if (ata[i]) {
305 | fw.write(label[i] + ": type=" + ataType[i]);
306 | if (ataType[i].equals("cdrom")) {
307 | fw.write(", status=inserted");
308 | }
309 | if (!ataMode[i].equals("") && !ataType[i].equals("cdrom")) {
310 | fw.write(", mode=" + ataMode[i]);
311 | }
312 | fw.write(", path=\"" + ataImage[i] + "\"\n");
313 | }
314 | }
315 |
316 | fw.write("boot: " + boot + "\n");
317 | fw.write("megs: " + megs + "\n");
318 | fw.write("sound: waveoutdrv=sdl\n");
319 | if (useSpeaker)
320 | fw.write("speaker: enabled=1, mode=sound\n");
321 | if (useSb16)
322 | fw.write("sb16: wavemode=1, dmatimer=500000\n");
323 | if (useEs1370)
324 | fw.write("es1370: enabled=1, wavemode=1\n");
325 | if (useVoodoo)
326 | fw.write("voodoo: enabled=1, model=voodoo1\n");
327 | fw.write("mouse: enabled=1\n");
328 | fw.write("clock: sync=" + clockSync + ", time0=local\n");
329 | fw.write("debug: action=ignore\n");
330 | fw.write("info: action=ignore\n");
331 | fw.write("error: action=ignore\n");
332 | fw.write("panic: action=report\n");
333 | fw.write("log: bochsout.txt\n");
334 | fw.close();
335 | }
336 | }
337 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-land/fragment_hardware.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
19 |
20 |
25 |
26 |
36 |
37 |
42 |
43 |
49 |
50 |
57 |
58 |
59 |
60 |
70 |
71 |
75 |
76 |
82 |
83 |
89 |
90 |
91 |
92 |
93 |
94 |
103 |
104 |
108 |
109 |
114 |
115 |
120 |
121 |
122 |
123 |
128 |
129 |
139 |
140 |
145 |
146 |
151 |
152 |
158 |
159 |
160 |
161 |
171 |
172 |
177 |
178 |
183 |
184 |
190 |
191 |
192 |
193 |
203 |
204 |
209 |
210 |
215 |
216 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
241 |
242 |
247 |
248 |
254 |
255 |
260 |
261 |
266 |
267 |
268 |
269 |
275 |
276 |
281 |
282 |
287 |
288 |
289 |
290 |
296 |
297 |
302 |
303 |
308 |
309 |
310 |
311 |
317 |
318 |
323 |
324 |
329 |
330 |
331 |
332 |
338 |
339 |
344 |
345 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_hardware.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
24 |
25 |
30 |
31 |
37 |
38 |
45 |
46 |
47 |
48 |
55 |
56 |
66 |
67 |
71 |
72 |
78 |
79 |
85 |
86 |
87 |
88 |
98 |
99 |
103 |
104 |
109 |
110 |
115 |
116 |
117 |
118 |
119 |
120 |
126 |
127 |
133 |
134 |
143 |
144 |
149 |
150 |
155 |
156 |
162 |
163 |
164 |
165 |
175 |
176 |
181 |
182 |
187 |
188 |
194 |
195 |
196 |
197 |
207 |
208 |
213 |
214 |
219 |
220 |
227 |
228 |
229 |
230 |
231 |
232 |
242 |
243 |
248 |
249 |
255 |
256 |
261 |
262 |
267 |
268 |
269 |
270 |
276 |
277 |
282 |
283 |
288 |
289 |
290 |
291 |
297 |
298 |
303 |
304 |
309 |
310 |
311 |
312 |
318 |
319 |
324 |
325 |
330 |
331 |
332 |
333 |
339 |
340 |
345 |
346 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
--------------------------------------------------------------------------------
/app/src/main/res/layout-land/fragment_storage.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
20 |
21 |
29 |
30 |
35 |
36 |
43 |
44 |
51 |
52 |
53 |
54 |
60 |
61 |
62 |
63 |
71 |
72 |
77 |
78 |
85 |
86 |
93 |
94 |
95 |
101 |
102 |
103 |
104 |
113 |
114 |
120 |
121 |
126 |
127 |
128 |
129 |
130 |
131 |
138 |
139 |
146 |
147 |
156 |
157 |
165 |
166 |
174 |
175 |
185 |
186 |
187 |
188 |
195 |
196 |
203 |
204 |
213 |
214 |
222 |
223 |
231 |
232 |
242 |
243 |
244 |
245 |
252 |
253 |
260 |
261 |
270 |
271 |
279 |
280 |
288 |
289 |
299 |
300 |
301 |
302 |
309 |
310 |
317 |
318 |
327 |
328 |
336 |
337 |
345 |
346 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/fragment_storage.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
13 |
14 |
22 |
23 |
31 |
32 |
37 |
38 |
44 |
45 |
52 |
53 |
54 |
55 |
62 |
63 |
64 |
65 |
74 |
75 |
80 |
81 |
87 |
88 |
95 |
96 |
97 |
98 |
105 |
106 |
107 |
108 |
109 |
110 |
117 |
118 |
121 |
122 |
128 |
129 |
136 |
137 |
144 |
145 |
146 |
147 |
150 |
151 |
158 |
159 |
170 |
171 |
172 |
173 |
174 |
175 |
182 |
183 |
186 |
187 |
193 |
194 |
201 |
202 |
209 |
210 |
211 |
212 |
215 |
216 |
223 |
224 |
235 |
236 |
237 |
238 |
239 |
240 |
247 |
248 |
251 |
252 |
258 |
259 |
266 |
267 |
274 |
275 |
276 |
277 |
280 |
281 |
288 |
289 |
300 |
301 |
302 |
303 |
304 |
305 |
312 |
313 |
316 |
317 |
323 |
324 |
331 |
332 |
339 |
340 |
341 |
342 |
345 |
346 |
353 |
354 |
365 |
366 |
367 |
368 |
369 |
370 |
378 |
379 |
384 |
385 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
--------------------------------------------------------------------------------
/app/src/main/java/net/sourceforge/bochs/StorageTabFragment.java:
--------------------------------------------------------------------------------
1 | package net.sourceforge.bochs;
2 |
3 | import android.content.SharedPreferences;
4 | import android.os.Bundle;
5 | import android.support.v4.app.Fragment;
6 | import android.view.LayoutInflater;
7 | import android.view.View;
8 | import android.view.View.OnClickListener;
9 | import android.view.ViewGroup;
10 | import android.widget.AdapterView;
11 | import android.widget.AdapterView.OnItemSelectedListener;
12 | import android.widget.ArrayAdapter;
13 | import android.widget.Button;
14 | import android.widget.CheckBox;
15 | import android.widget.CompoundButton;
16 | import android.widget.Spinner;
17 | import android.widget.SpinnerAdapter;
18 | import android.widget.TextView;
19 |
20 | import java.io.File;
21 | import java.util.Arrays;
22 | import java.util.List;
23 |
24 | import static android.content.Context.MODE_PRIVATE;
25 |
26 | public class StorageTabFragment extends Fragment implements OnClickListener {
27 | private SharedPreferences sPref;
28 | private final int floppyNum = Config.floppyNum;
29 | private final int ataNum = Config.ataNum;
30 | private final int FLOPPY_A = Config.FLOPPY_A;
31 | private final int FLOPPY_B = Config.FLOPPY_B;
32 | private final int ATA_0_MASTER = Config.ATA_0_MASTER;
33 | private final int ATA_0_SLAVE = Config.ATA_0_SLAVE;
34 | private final int ATA_1_MASTER = Config.ATA_1_MASTER;
35 | private final int ATA_1_SLAVE = Config.ATA_1_SLAVE;
36 | private final String NONE = Config.NONE;
37 | private final String DISK = Config.DISK;
38 | private final String CDROM = Config.CDROM;
39 | private final String FLOPPY = Config.FLOPPY;
40 | private final String VFAT = Config.VFAT;
41 | private TextView tvFloppy[] = new TextView[floppyNum];
42 | private CheckBox cbFloppy[] = new CheckBox[floppyNum];
43 | private Button btBrowseFloppy[] = new Button[floppyNum];
44 | private TextView tvAta[] = new TextView[ataNum];
45 | private CheckBox cbVvfatAta[] = new CheckBox[ataNum];
46 | private CheckBox cbAta[] = new CheckBox[ataNum];
47 | private Button btBrowseAta[] = new Button[ataNum];
48 | private Spinner spAtaType[] = new Spinner[ataNum];
49 |
50 | private String m_chosenDir = "";
51 | private boolean m_newFolderEnabled = true;
52 | final String SAVED_PATH = "saved_path";
53 |
54 | private enum Requestor {ATA0_MASTER, ATA0_SLAVE, ATA1_MASTER, ATA1_SLAVE, FLOPPY_A, FLOPPY_B}
55 |
56 | @Override
57 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
58 | Bundle savedInstanceState) {
59 |
60 | View rootView = inflater.inflate(R.layout.fragment_storage, container, false);
61 | setupView(rootView);
62 |
63 | return rootView;
64 | }
65 |
66 | @Override
67 | public void onClick(View view) {
68 | switch (view.getId()) {
69 | case R.id.storageButtonFloppyA:
70 | fileSelection(Requestor.FLOPPY_A, FLOPPY);
71 | break;
72 | case R.id.storageButtonFloppyB:
73 | fileSelection(Requestor.FLOPPY_B, FLOPPY);
74 | break;
75 | case R.id.storageButtonAta0m:
76 | if (cbVvfatAta[ATA_0_MASTER].isChecked())
77 | dirSelection(Requestor.ATA0_MASTER);
78 | else
79 | fileSelection(Requestor.ATA0_MASTER, Config.ataType[ATA_0_MASTER]);
80 | break;
81 | case R.id.storageButtonAta0s:
82 | if (cbVvfatAta[ATA_0_SLAVE].isChecked())
83 | dirSelection(Requestor.ATA0_SLAVE);
84 | else
85 | fileSelection(Requestor.ATA0_SLAVE, Config.ataType[ATA_0_SLAVE]);
86 | break;
87 | case R.id.storageButtonAta1m:
88 | if (cbVvfatAta[ATA_1_MASTER].isChecked())
89 | dirSelection(Requestor.ATA1_MASTER);
90 | else
91 | fileSelection(Requestor.ATA1_MASTER, Config.ataType[ATA_1_MASTER]);
92 | break;
93 | case R.id.storageButtonAta1s:
94 | if (cbVvfatAta[ATA_1_SLAVE].isChecked())
95 | dirSelection(Requestor.ATA1_SLAVE);
96 | else
97 | fileSelection(Requestor.ATA1_SLAVE, Config.ataType[ATA_1_SLAVE]);
98 | break;
99 | }
100 | }
101 |
102 | private void setupView(View rootView) {
103 | final List typeList = Arrays.asList(DISK, CDROM);
104 | final List bootList = Arrays.asList(DISK, CDROM, FLOPPY);
105 | cbFloppy[FLOPPY_A] = (CheckBox) rootView.findViewById(R.id.storageCheckBoxFloppyA);
106 | tvFloppy[FLOPPY_A] = (TextView) rootView.findViewById(R.id.storageTextViewFloppyA);
107 | btBrowseFloppy[FLOPPY_A] = (Button) rootView.findViewById(R.id.storageButtonFloppyA);
108 | cbFloppy[FLOPPY_B] = (CheckBox) rootView.findViewById(R.id.storageCheckBoxFloppyB);
109 | tvFloppy[FLOPPY_B] = (TextView) rootView.findViewById(R.id.storageTextViewFloppyB);
110 | btBrowseFloppy[FLOPPY_B] = (Button) rootView.findViewById(R.id.storageButtonFloppyB);
111 | cbAta[ATA_0_MASTER] = (CheckBox) rootView.findViewById(R.id.storageCheckBoxAta0m);
112 | tvAta[ATA_0_MASTER] = (TextView) rootView.findViewById(R.id.storageTextViewAta0m);
113 | cbVvfatAta[ATA_0_MASTER] = (CheckBox) rootView.findViewById(R.id.storageCheckBoxAta0mVvfat);
114 | btBrowseAta[ATA_0_MASTER] = (Button) rootView.findViewById(R.id.storageButtonAta0m);
115 | spAtaType[ATA_0_MASTER] = (Spinner) rootView.findViewById(R.id.storageSpinnerAta0m);
116 | cbAta[ATA_0_SLAVE] = (CheckBox) rootView.findViewById(R.id.storageCheckBoxAta0s);
117 | tvAta[ATA_0_SLAVE] = (TextView) rootView.findViewById(R.id.storageTextViewAta0s);
118 | cbVvfatAta[ATA_0_SLAVE] = (CheckBox) rootView.findViewById(R.id.storageCheckBoxAta0sVvfat);
119 | btBrowseAta[ATA_0_SLAVE] = (Button) rootView.findViewById(R.id.storageButtonAta0s);
120 | spAtaType[ATA_0_SLAVE] = (Spinner) rootView.findViewById(R.id.storageSpinnerAta0s);
121 | cbAta[ATA_1_MASTER] = (CheckBox) rootView.findViewById(R.id.storageCheckBoxAta1m);
122 | tvAta[ATA_1_MASTER] = (TextView) rootView.findViewById(R.id.storageTextViewAta1m);
123 | cbVvfatAta[ATA_1_MASTER] = (CheckBox) rootView.findViewById(R.id.storageCheckBoxAta1mVvfat);
124 | btBrowseAta[ATA_1_MASTER] = (Button) rootView.findViewById(R.id.storageButtonAta1m);
125 | spAtaType[ATA_1_MASTER] = (Spinner) rootView.findViewById(R.id.storageSpinnerAta1m);
126 | cbAta[ATA_1_SLAVE] = (CheckBox) rootView.findViewById(R.id.storageCheckBoxAta1s);
127 | tvAta[ATA_1_SLAVE] = (TextView) rootView.findViewById(R.id.storageTextViewAta1s);
128 | cbVvfatAta[ATA_1_SLAVE] = (CheckBox) rootView.findViewById(R.id.storageCheckBoxAta1sVvfat);
129 | btBrowseAta[ATA_1_SLAVE] = (Button) rootView.findViewById(R.id.storageButtonAta1s);
130 | spAtaType[ATA_1_SLAVE] = (Spinner) rootView.findViewById(R.id.storageSpinnerAta1s);
131 |
132 | // setup boot selection logic
133 | Spinner spBoot = (Spinner) rootView.findViewById(R.id.storageSpinnerBoot);
134 | SpinnerAdapter adapterBoot = new ArrayAdapter(getActivity(), R.layout.spinner_row, bootList);
135 | spBoot.setAdapter(adapterBoot);
136 | spBoot.setSelection(bootList.indexOf(Config.boot));
137 | spBoot.setOnItemSelectedListener(new OnItemSelectedListener() {
138 |
139 | @Override
140 | public void onItemSelected(AdapterView> p1, View p2, int p3, long p4) {
141 | Config.boot = bootList.get(p3);
142 | }
143 |
144 | @Override
145 | public void onNothingSelected(AdapterView> p1) {
146 |
147 | }
148 | });
149 |
150 | // setup floppy logic
151 | for (int i = 0; i < floppyNum; i++) {
152 | cbFloppy[i].setChecked(Config.floppy[i]);
153 | tvFloppy[i].setText(MainActivity.getFileName(Config.floppyImage[i]));
154 | tvFloppy[i].setEnabled(Config.floppy[i]);
155 | btBrowseFloppy[i].setEnabled(Config.floppy[i]);
156 |
157 | final int j = i;
158 |
159 | cbFloppy[i].setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
160 |
161 | @Override
162 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
163 | Config.floppy[j] = cbFloppy[j].isChecked();
164 | btBrowseFloppy[j].setEnabled(Config.floppy[j]);
165 | tvFloppy[j].setEnabled(Config.floppy[j]);
166 | }
167 | }
168 | );
169 |
170 | btBrowseFloppy[i].setOnClickListener(this);
171 | }
172 |
173 | //setup ata logic
174 | SpinnerAdapter adapterType = new ArrayAdapter(getActivity(), R.layout.spinner_row, typeList);
175 | for (int i = 0; i < ataNum; i++) {
176 | cbAta[i].setChecked(Config.ata[i]);
177 | tvAta[i].setText(MainActivity.getFileName(Config.ataImage[i]));
178 | tvAta[i].setEnabled(Config.ata[i]);
179 | cbVvfatAta[i].setChecked(Config.ataMode[i].equals(VFAT));
180 | cbVvfatAta[i].setEnabled(Config.ata[i]);
181 | btBrowseAta[i].setEnabled(Config.ata[i]);
182 | spAtaType[i].setEnabled(Config.ata[i]);
183 | spAtaType[i].setAdapter(adapterType);
184 | spAtaType[i].setSelection(typeList.indexOf(Config.ataType[i]));
185 |
186 | final int j = i;
187 |
188 | cbAta[i].setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
189 |
190 | @Override
191 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
192 | Config.ata[j] = cbAta[j].isChecked();
193 | btBrowseAta[j].setEnabled(Config.ata[j]);
194 | tvAta[j].setEnabled(Config.ata[j]);
195 | spAtaType[j].setEnabled(Config.ata[j]);
196 | if (!Config.ataType[j].equals(CDROM))
197 | cbVvfatAta[j].setEnabled(Config.ata[j]);
198 |
199 | }
200 | }
201 | );
202 |
203 | spAtaType[i].setOnItemSelectedListener(new OnItemSelectedListener() {
204 |
205 | @Override
206 | public void onItemSelected(AdapterView> p1, View p2, int p3, long p4) {
207 | if (!Config.ataType[j].equals(typeList.get(p3))) {
208 | Config.ataImage[j] = NONE;
209 | tvAta[j].setText(NONE);
210 | }
211 | Config.ataType[j] = typeList.get(p3);
212 | if (!Config.ataType[j].equals(CDROM) && cbAta[j].isChecked()) {
213 | cbVvfatAta[j].setEnabled(true);
214 | } else {
215 | cbVvfatAta[j].setChecked(false);
216 | cbVvfatAta[j].setEnabled(false);
217 | }
218 | }
219 |
220 | @Override
221 | public void onNothingSelected(AdapterView> p1) {
222 |
223 | }
224 | });
225 |
226 | cbVvfatAta[i].setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
227 |
228 | @Override
229 | public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
230 | Config.ataMode[j] = isChecked ? VFAT : "";
231 | Config.ataImage[j] = NONE;
232 | tvAta[j].setText(NONE);
233 | }
234 | });
235 |
236 |
237 | btBrowseAta[i].setOnClickListener(this);
238 | }
239 |
240 | }
241 |
242 | private void dirSelection(final Requestor num) {
243 | // Create DirectoryChooserDialog and register a callback
244 | DirectoryChooserDialog directoryChooserDialog =
245 | new DirectoryChooserDialog(getActivity(),
246 | new DirectoryChooserDialog.ChosenDirectoryListener() {
247 | @Override
248 | public void onChosenDir(String chosenDir) {
249 | m_chosenDir = chosenDir;
250 | switch (num) {
251 | case ATA0_MASTER:
252 | tvAta[ATA_0_MASTER].setText(chosenDir);
253 | Config.ataImage[ATA_0_MASTER] = chosenDir;
254 | break;
255 | case ATA0_SLAVE:
256 | tvAta[ATA_0_SLAVE].setText(chosenDir);
257 | Config.ataImage[ATA_0_SLAVE] = chosenDir;
258 | break;
259 | case ATA1_MASTER:
260 | tvAta[ATA_1_MASTER].setText(chosenDir);
261 | Config.ataImage[ATA_1_MASTER] = chosenDir;
262 | break;
263 | case ATA1_SLAVE:
264 | tvAta[ATA_1_SLAVE].setText(chosenDir);
265 | Config.ataImage[ATA_1_SLAVE] = chosenDir;
266 | break;
267 | }
268 | }
269 | });
270 | // Toggle new folder button enabling
271 | directoryChooserDialog.setNewFolderEnabled(m_newFolderEnabled);
272 | // Load directory chooser dialog for initial 'm_chosenDir' directory.
273 | // The registered callback will be called upon final directory selection.
274 | directoryChooserDialog.chooseDirectory(m_chosenDir);
275 | m_newFolderEnabled = !m_newFolderEnabled;
276 | }
277 |
278 | private void fileSelection(final Requestor num, String type) {
279 | // Set up extension
280 | String extension[] = null;
281 | switch (type) {
282 | case DISK:
283 | extension = new String[]{".img", ".vmdk", ".vhd", ".vdi"};
284 | break;
285 | case CDROM:
286 | extension = new String[]{".iso"};
287 | break;
288 | case FLOPPY:
289 | extension = new String[]{".img", ".ima"};
290 | break;
291 | }
292 | FileChooser filechooser = new FileChooser(getActivity(), getLastPath(), extension);
293 | filechooser.setFileListener(new FileChooser.FileSelectedListener() {
294 | @Override
295 | public void fileSelected(final File file) {
296 | String filename = file.getAbsolutePath();
297 | saveLastPath(file.getPath());
298 | switch (num) {
299 | case ATA0_MASTER:
300 | tvAta[ATA_0_MASTER].setText(file.getName());
301 | Config.ataImage[ATA_0_MASTER] = filename;
302 | Config.ataMode[ATA_0_MASTER] = getMode(file.getName());
303 | break;
304 | case ATA0_SLAVE:
305 | tvAta[ATA_0_SLAVE].setText(file.getName());
306 | Config.ataImage[ATA_0_SLAVE] = filename;
307 | Config.ataMode[ATA_0_SLAVE] = getMode(file.getName());
308 | break;
309 | case ATA1_MASTER:
310 | tvAta[ATA_1_MASTER].setText(file.getName());
311 | Config.ataImage[ATA_1_MASTER] = filename;
312 | Config.ataMode[ATA_1_MASTER] = getMode(file.getName());
313 | break;
314 | case ATA1_SLAVE:
315 | tvAta[ATA_1_SLAVE].setText(file.getName());
316 | Config.ataImage[ATA_1_SLAVE] = filename;
317 | Config.ataMode[ATA_1_SLAVE] = getMode(file.getName());
318 | break;
319 | case FLOPPY_A:
320 | tvFloppy[FLOPPY_A].setText(file.getName());
321 | Config.floppyImage[FLOPPY_A] = filename;
322 | break;
323 | case FLOPPY_B:
324 | tvFloppy[FLOPPY_B].setText(file.getName());
325 | Config.floppyImage[FLOPPY_B] = filename;
326 | break;
327 | }
328 |
329 | }
330 | });
331 |
332 | filechooser.showDialog();
333 | }
334 |
335 | private String getMode(String str) {
336 | String result = "";
337 | if (str.endsWith(".vmdk"))
338 | result = "vmware4";
339 | else if (str.endsWith(".vhd"))
340 | result = "vpc";
341 | else if (str.endsWith(".vdi"))
342 | result = "vbox";
343 | return result;
344 | }
345 |
346 | private void saveLastPath(String filePath) {
347 | String dirPath;
348 | if (filePath.contains("/"))
349 | dirPath = filePath.substring(0, filePath.lastIndexOf('/'));
350 | else
351 | dirPath = filePath;
352 | sPref = getActivity().getPreferences(MODE_PRIVATE);
353 | SharedPreferences.Editor ed = sPref.edit();
354 | ed.putString(SAVED_PATH, dirPath);
355 | ed.apply();
356 | }
357 |
358 | private String getLastPath() {
359 | sPref = getActivity().getPreferences(MODE_PRIVATE);
360 | return sPref.getString(SAVED_PATH, null);
361 | }
362 |
363 | }
364 |
--------------------------------------------------------------------------------
/app/src/main/java/net/sourceforge/bochs/HardwareTabFragment.java:
--------------------------------------------------------------------------------
1 | package net.sourceforge.bochs;
2 |
3 | import android.os.Bundle;
4 | import android.support.v4.app.Fragment;
5 | import android.view.LayoutInflater;
6 | import android.view.View;
7 | import android.view.View.OnClickListener;
8 | import android.view.ViewGroup;
9 | import android.widget.AdapterView;
10 | import android.widget.AdapterView.OnItemSelectedListener;
11 | import android.widget.ArrayAdapter;
12 | import android.widget.RadioButton;
13 | import android.widget.SeekBar;
14 | import android.widget.SeekBar.OnSeekBarChangeListener;
15 | import android.widget.Spinner;
16 | import android.widget.SpinnerAdapter;
17 | import android.widget.TextView;
18 |
19 | import net.sourceforge.bochs.entity.CpuModel;
20 | import net.sourceforge.bochs.entity.EthernetCard;
21 | import net.sourceforge.bochs.entity.SoundCard;
22 | import net.sourceforge.bochs.entity.VgaCard;
23 |
24 | import org.json.JSONArray;
25 | import org.json.JSONException;
26 | import org.json.JSONObject;
27 |
28 | import java.util.ArrayList;
29 | import java.util.Arrays;
30 | import java.util.List;
31 | import java.util.Scanner;
32 |
33 | public class HardwareTabFragment extends Fragment {
34 | private TextView tvCpuDescription;
35 | private Spinner spVga;
36 | private TextView tvVgaDescription;
37 | private Spinner spSound;
38 | private TextView tvSoundDescription;
39 | private Spinner spEthernet;
40 | private TextView tvEthernetDescription;
41 | private TextView tvMemory;
42 | private Spinner[] spSlot = new Spinner[5];
43 | private ArrayAdapter slotAdapter[] = new ArrayAdapter[5];
44 | private List cpuModel = new ArrayList<>();
45 | private List vgaCard = new ArrayList<>();
46 | private List soundCard = new ArrayList<>();
47 | private List ethernetCard = new ArrayList<>();
48 | private List[] slotList = new List[5];
49 |
50 | @Override
51 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
52 | Bundle savedInstanceState) {
53 |
54 | View rootView = inflater.inflate(R.layout.fragment_hardware, container, false);
55 | setupView(rootView);
56 |
57 | return rootView;
58 | }
59 |
60 | private void setupView(View rootView) {
61 | final int memoryStep = 8;
62 | final int minValueMemory = 8;
63 | for (int i = 0; i < 5; i++)
64 | slotList[i] = new ArrayList<>();
65 | updateSlotLists();
66 |
67 | if (cpuModel.size() == 0)
68 | readCpuList();
69 |
70 | Spinner spCpuModel = (Spinner) rootView.findViewById(R.id.hardwareSpinnerCpuModel);
71 | RadioButton rbI430fx = (RadioButton) rootView.findViewById(R.id.hardwareRadioButtonI430fx);
72 | RadioButton rbI440fx = (RadioButton) rootView.findViewById(R.id.hardwareRadioButtonI440fx);
73 | tvCpuDescription = (TextView) rootView.findViewById(R.id.hardwareTextViewCpuDesc);
74 | spVga = (Spinner) rootView.findViewById(R.id.hardwareSpinnerVga);
75 | tvVgaDescription = (TextView) rootView.findViewById(R.id.hardwareTextViewVgaDesc);
76 | spSound = (Spinner) rootView.findViewById(R.id.hardwareSpinnerSound);
77 | tvSoundDescription = (TextView) rootView.findViewById(R.id.hardwareTextViewSoundDesc);
78 | spEthernet = (Spinner) rootView.findViewById(R.id.hardwareSpinnerEthernet);
79 | tvEthernetDescription = (TextView) rootView.findViewById(R.id.hardwareTextViewEthernetDesc);
80 | SeekBar sbMemory = (SeekBar) rootView.findViewById(R.id.hardwareSeekBarMemory);
81 | tvMemory = (TextView) rootView.findViewById(R.id.hardwareTextViewMemory);
82 | spSlot[0] = (Spinner) rootView.findViewById(R.id.hardwareSpinnerSlot1);
83 | spSlot[1] = (Spinner) rootView.findViewById(R.id.hardwareSpinnerSlot2);
84 | spSlot[2] = (Spinner) rootView.findViewById(R.id.hardwareSpinnerSlot3);
85 | spSlot[3] = (Spinner) rootView.findViewById(R.id.hardwareSpinnerSlot4);
86 | spSlot[4] = (Spinner) rootView.findViewById(R.id.hardwareSpinnerSlot5);
87 | SpinnerAdapter cpuModelAdapter = new ArrayAdapter(getActivity(), R.layout.spinner_row, getCpuModelValues());
88 | for (int i = 0; i < 5; i++)
89 | slotAdapter[i] = new ArrayAdapter(getActivity(), R.layout.spinner_row, slotList[i]);
90 | SpinnerAdapter vgaAdapter = new ArrayAdapter(getActivity(), R.layout.spinner_row, getVgaCardValues());
91 | SpinnerAdapter soundAdapter = new ArrayAdapter(getActivity(), R.layout.spinner_row, getSoundCardValues());
92 | SpinnerAdapter ethernetAdapter = new ArrayAdapter(getActivity(), R.layout.spinner_row, getEthernetCardValues());
93 | spCpuModel.setAdapter(cpuModelAdapter);
94 | spVga.setAdapter(vgaAdapter);
95 | spSound.setAdapter(soundAdapter);
96 | spEthernet.setAdapter(ethernetAdapter);
97 | for (int i = 0; i < 5; i++)
98 | spSlot[i].setAdapter(slotAdapter[i]);
99 | int selectedCpuModel = getCpuModelValues().indexOf(Config.cpuModel);
100 | spCpuModel.setSelection(selectedCpuModel);
101 | tvCpuDescription.setText(cpuModel.get(selectedCpuModel).getDescription());
102 | rbI430fx.setChecked(Config.chipset.equals("i430fx"));
103 | rbI440fx.setChecked(Config.chipset.equals("i440fx"));
104 | sbMemory.setProgress((Config.megs / memoryStep) - minValueMemory);
105 | tvMemory.setText(String.format("%s mb", Config.megs));
106 | Integer[] selectedSlot = new Integer[5];
107 | for (int i = 0; i < spSlot.length; i++) {
108 | selectedSlot[i] = slotList[i].indexOf(Config.slot[i]);
109 | spSlot[i].setSelection((selectedSlot[i] == -1) ? 0 : selectedSlot[i]);
110 | }
111 | checkVga();
112 | checkSound();
113 | checkEthernet();
114 |
115 | spCpuModel.setOnItemSelectedListener(new OnItemSelectedListener() {
116 |
117 | @Override
118 | public void onItemSelected(AdapterView> p1, View p2, int p3, long p4) {
119 | Config.cpuModel = getCpuModelValues().get(p3);
120 | int num = getCpuModelValues().indexOf(Config.cpuModel);
121 | tvCpuDescription.setText(cpuModel.get(num).getDescription());
122 | }
123 |
124 | @Override
125 | public void onNothingSelected(AdapterView> p1) {
126 | }
127 | });
128 |
129 | spVga.setOnItemSelectedListener(new OnItemSelectedListener() {
130 |
131 | @Override
132 | public void onItemSelected(AdapterView> p1, View p2, int p3, long p4) {
133 | tvVgaDescription.setText(vgaCard.get(p3).getDescription());
134 | switch (p3) {
135 | case 0:
136 | Config.vgaExtension = "vbe";
137 | Config.vgaRomImage = "VGABIOS-lgpl-latest";
138 | setFreePciSlot("pcivga");
139 | setFreePciSlot("cirrus");
140 | break;
141 | case 1:
142 | Config.vgaExtension = "vbe";
143 | Config.vgaRomImage = "VGABIOS-lgpl-latest";
144 | setFreePciSlot("cirrus");
145 | spSlot[0].setSelection(slotList[0].indexOf("pcivga"));
146 | slotAdapter[0].notifyDataSetChanged();
147 | break;
148 | case 2:
149 | Config.vgaExtension = "cirrus";
150 | Config.vgaRomImage = "VGABIOS-lgpl-latest-cirrus";
151 | setFreePciSlot("pcivga");
152 | setFreePciSlot("cirrus");
153 | break;
154 | case 3:
155 | Config.vgaExtension = "cirrus";
156 | Config.vgaRomImage = "VGABIOS-lgpl-latest-cirrus";
157 | setFreePciSlot("pcivga");
158 | spSlot[0].setSelection(slotList[0].indexOf("cirrus"));
159 | slotAdapter[0].notifyDataSetChanged();
160 | break;
161 | }
162 | }
163 |
164 | @Override
165 | public void onNothingSelected(AdapterView> p1) {
166 | }
167 | });
168 |
169 | spSound.setOnItemSelectedListener(new OnItemSelectedListener() {
170 |
171 | @Override
172 | public void onItemSelected(AdapterView> p1, View p2, int p3, long p4) {
173 | tvSoundDescription.setText(soundCard.get(p3).getDescription());
174 | switch (p3) {
175 | case 0:
176 | Config.useSb16 = false;
177 | Config.useEs1370 = false;
178 | setFreePciSlot("es1370");
179 | break;
180 | case 1:
181 | Config.useSb16 = true;
182 | Config.useEs1370 = false;
183 | setFreePciSlot("es1370");
184 | break;
185 | case 2:
186 | Config.useSb16 = false;
187 | Config.useEs1370 = true;
188 | spSlot[2].setSelection(slotList[2].indexOf("es1370"));
189 | slotAdapter[2].notifyDataSetChanged();
190 | break;
191 | }
192 | }
193 |
194 | @Override
195 | public void onNothingSelected(AdapterView> p1) {
196 | }
197 | });
198 |
199 | spEthernet.setOnItemSelectedListener(new OnItemSelectedListener() {
200 |
201 | @Override
202 | public void onItemSelected(AdapterView> p1, View p2, int p3, long p4) {
203 | tvEthernetDescription.setText(ethernetCard.get(p3).getDescription());
204 | switch (p3) {
205 | case 0:
206 | Config.useNe2000 = false;
207 | Config.useRtl8029 = false;
208 | Config.useE1000 = false;
209 | setFreePciSlot("ne2k");
210 | setFreePciSlot("e1000");
211 | break;
212 | case 1:
213 | Config.useNe2000 = true;
214 | Config.useRtl8029 = false;
215 | Config.useE1000 = false;
216 | setFreePciSlot("ne2k");
217 | setFreePciSlot("e1000");
218 | break;
219 | case 2:
220 | Config.useNe2000 = false;
221 | Config.useRtl8029 = true;
222 | Config.useE1000 = false;
223 | setFreePciSlot("e1000");
224 | spSlot[1].setSelection(slotList[1].indexOf("ne2k"));
225 | slotAdapter[1].notifyDataSetChanged();
226 | break;
227 | case 3:
228 | Config.useNe2000 = false;
229 | Config.useRtl8029 = false;
230 | Config.useE1000 = true;
231 | setFreePciSlot("ne2k");
232 | spSlot[1].setSelection(slotList[1].indexOf("e1000"));
233 | slotAdapter[1].notifyDataSetChanged();
234 | break;
235 | }
236 | }
237 |
238 | @Override
239 | public void onNothingSelected(AdapterView> p1) {
240 | }
241 | });
242 |
243 | for (int i=0; i<=4; i++) {
244 | final int finalI = i;
245 | spSlot[i].setOnItemSelectedListener(new OnItemSelectedListener() {
246 |
247 | @Override
248 | public void onItemSelected(AdapterView> p1, View p2, int p3, long p4) {
249 | String str = slotList[finalI].get(p3);
250 | Config.slot[finalI] = (p3 == 0) ? "" : str;
251 | setOnInConfig(str);
252 | updateSlotLists();
253 | checkVga();
254 | checkSound();
255 | checkEthernet();
256 | }
257 |
258 | @Override
259 | public void onNothingSelected(AdapterView> p1) {
260 | }
261 | });
262 | }
263 |
264 | sbMemory.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {
265 |
266 | @Override
267 | public void onProgressChanged(SeekBar p1, int progress, boolean p3) {
268 | progress = progress * memoryStep;
269 | tvMemory.setText(String.format("%s mb", (minValueMemory + progress)));
270 | Config.megs = minValueMemory + progress;
271 | }
272 |
273 | @Override
274 | public void onStartTrackingTouch(SeekBar p1) {
275 | }
276 |
277 | @Override
278 | public void onStopTrackingTouch(SeekBar p1) {
279 | }
280 | });
281 |
282 | OnClickListener hwOnClick = new OnClickListener() {
283 |
284 | @Override
285 | public void onClick(View p1) {
286 | Config.chipset = (p1.getId() == R.id.hardwareRadioButtonI430fx) ? "i430fx" : "i440fx";
287 | }
288 | };
289 |
290 | rbI430fx.setOnClickListener(hwOnClick);
291 | rbI440fx.setOnClickListener(hwOnClick);
292 | }
293 |
294 | private void readCpuList() {
295 | Scanner sc = new Scanner(getResources().openRawResource(R.raw.data_json)).useDelimiter("[\n]");
296 | StringBuilder sb = new StringBuilder();
297 | while (sc.hasNext()) {
298 | sb.append(sc.next()).append("\n");
299 | }
300 | sc.close();
301 |
302 | JSONObject dataJsonObj = null;
303 | try {
304 | dataJsonObj = new JSONObject(sb.toString());
305 | JSONArray cpulist = dataJsonObj.getJSONArray("cpulist");
306 | for (int i = 0; i < cpulist.length(); i++) {
307 | JSONObject model = cpulist.getJSONObject(i);
308 | String value = model.getString("value");
309 | String description = model.getString("description");
310 | String required = model.getString("required");
311 | cpuModel.add(new CpuModel(value, description, required));
312 | }
313 | JSONArray vgalist = dataJsonObj.getJSONArray("vgalist");
314 | for (int i = 0; i < vgalist.length(); i++) {
315 | JSONObject model = vgalist.getJSONObject(i);
316 | String value = model.getString("value");
317 | String description = model.getString("description");
318 | vgaCard.add(new VgaCard(value, description));
319 | }
320 | JSONArray soundlist = dataJsonObj.getJSONArray("soundlist");
321 | for (int i = 0; i < soundlist.length(); i++) {
322 | JSONObject model = soundlist.getJSONObject(i);
323 | String value = model.getString("value");
324 | String description = model.getString("description");
325 | soundCard.add(new SoundCard(value, description));
326 | }
327 | JSONArray ethernetlist = dataJsonObj.getJSONArray("ethernetlist");
328 | for (int i = 0; i < ethernetlist.length(); i++) {
329 | JSONObject model = ethernetlist.getJSONObject(i);
330 | String value = model.getString("value");
331 | String description = model.getString("description");
332 | ethernetCard.add(new EthernetCard(value, description));
333 | }
334 | } catch (JSONException e) {
335 | e.printStackTrace();
336 | }
337 | }
338 |
339 | private List getCpuModelValues() {
340 | List result = new ArrayList<>();
341 | for (CpuModel cm : cpuModel) {
342 | result.add(cm.getValue());
343 | }
344 | return result;
345 | }
346 |
347 | private List getVgaCardValues() {
348 | List result = new ArrayList<>();
349 | for (VgaCard vc : vgaCard) {
350 | result.add(vc.getValue());
351 | }
352 | return result;
353 | }
354 |
355 | private List getSoundCardValues() {
356 | List result = new ArrayList<>();
357 | for (SoundCard sc : soundCard) {
358 | result.add(sc.getValue());
359 | }
360 | return result;
361 | }
362 |
363 | private List getEthernetCardValues() {
364 | List result = new ArrayList<>();
365 | for (EthernetCard ec : ethernetCard) {
366 | result.add(ec.getValue());
367 | }
368 | return result;
369 | }
370 |
371 | private int getfreePciSlot() {
372 | for (int i = 0; i < Config.slot.length; i++) {
373 | if (Config.slot[i].equals("")) {
374 | return i;
375 | }
376 | }
377 | return -1;
378 | }
379 |
380 | private boolean checkPciSlotFor(String str) {
381 | for (int i = 0; i < Config.slot.length; i++) {
382 | if (Config.slot[i].equals(str)) {
383 | return true;
384 | }
385 | }
386 | return false;
387 | }
388 |
389 | private void setFreePciSlot(String str) {
390 | for (int i = 0; i < Config.slot.length; i++) {
391 | if (Config.slot[i].equals(str)) {
392 | Config.slot[i] = "";
393 | spSlot[i].setSelection(0);
394 | slotAdapter[i].notifyDataSetChanged();
395 | }
396 | }
397 | }
398 |
399 | private void checkVga() {
400 | if (Config.vgaExtension.equals("vbe")) {
401 | spVga.setSelection(checkPciSlotFor("pcivga") ? 1 : 0);
402 | } else if (Config.vgaExtension.equals("cirrus")) {
403 | spVga.setSelection(checkPciSlotFor("cirrus") ? 3 : 2);
404 | }
405 | }
406 |
407 | private void checkSound() {
408 | if (Config.useEs1370 && checkPciSlotFor("es1370"))
409 | spSound.setSelection(2);
410 | else if (Config.useSb16)
411 | spSound.setSelection(1);
412 | else
413 | spSound.setSelection(0);
414 | }
415 |
416 | private void checkEthernet() {
417 | if (Config.useE1000 && checkPciSlotFor("e1000"))
418 | spEthernet.setSelection(3);
419 | else if (checkPciSlotFor("ne2k"))
420 | spEthernet.setSelection(2);
421 | else if (Config.useNe2000)
422 | spEthernet.setSelection(1);
423 | else
424 | spEthernet.setSelection(0);
425 | }
426 |
427 | private void setOnInConfig(String str) {
428 | switch (str) {
429 | case "voodoo":
430 | Config.useVoodoo = true;
431 | break;
432 | case "es1370":
433 | Config.useEs1370 = true;
434 | break;
435 | case "ne2k":
436 | Config.useNe2000 = true;
437 | Config.useRtl8029 = true;
438 | break;
439 | case "e1000":
440 | Config.useE1000 = true;
441 | break;
442 | case "pcivga":
443 | Config.vgaExtension = "vbe";
444 | Config.vgaRomImage = "VGABIOS-lgpl-latest";
445 | break;
446 | case "cirrus":
447 | Config.vgaExtension = "cirrus";
448 | Config.vgaRomImage = "VGABIOS-lgpl-latest-cirrus";
449 | break;
450 | }
451 | }
452 |
453 | private List getSlotList(int num) {
454 | List list = new ArrayList<>();
455 | final List fullSlotList = Arrays.asList("none", "pcivga", "cirrus", "voodoo",
456 | "es1370", "ne2k", "e1000");
457 | list.addAll(fullSlotList);
458 | for (int i = 0; i < 5; i++) {
459 | list.remove(Config.slot[i]);
460 | }
461 | if (!Config.slot[num].isEmpty())
462 | list.add(Config.slot[num]);
463 | return list;
464 | }
465 |
466 | private void updateSlotLists() {
467 | for (int i = 0; i < 5; i++) {
468 | slotList[i].clear();
469 | slotList[i].addAll(getSlotList(i));
470 | if (slotAdapter[i] != null) {
471 | slotAdapter[i].notifyDataSetChanged();
472 | int selectedSlot = slotList[i].indexOf(Config.slot[i]);
473 | spSlot[i].setSelection((selectedSlot == -1) ? 0 : selectedSlot);
474 | }
475 | }
476 | }
477 |
478 | }
479 |
--------------------------------------------------------------------------------