mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 13:50:03 +00:00 
			
		
		
		
	Added basic UI; misc memory fixes
This commit is contained in:
		
							parent
							
								
									558e710e17
								
							
						
					
					
						commit
						26e90a99cd
					
				
					 13 changed files with 90 additions and 36 deletions
				
			
		
							
								
								
									
										13
									
								
								TODO
									
										
									
									
									
								
							
							
						
						
									
										13
									
								
								TODO
									
										
									
									
									
								
							|  | @ -1,8 +1,11 @@ | ||||||
| ☐ Save/load UI | ☐ Save/load UI | ||||||
|  |     ✔ Basic version @done(20-01-03 15:27) | ||||||
|  |     ☐ Multiple slots etc. | ||||||
| ✔ CPU @done(19-08-13 15:41) | ✔ CPU @done(19-08-13 15:41) | ||||||
| ✔ Memory @done(19-08-13 15:41) | ✔ Memory @done(19-08-13 15:41) | ||||||
|     ☐ Page tables |     ☐ Page tables | ||||||
|     ☐ Skip N3DS RAM if unused |     ✘ Skip N3DS RAM if unused @cancelled(20-01-03 15:26) | ||||||
|  |         Since no n3ds support, leave this for now | ||||||
| ✔ DSP @done(19-12-28 16:57) | ✔ DSP @done(19-12-28 16:57) | ||||||
|     Memory only |     Memory only | ||||||
| ✔ Service manager @started(19-12-23 00:36) @done(19-12-23 11:38) @lasted(11h2m3s) | ✔ Service manager @started(19-12-23 00:36) @done(19-12-23 11:38) @lasted(11h2m3s) | ||||||
|  | @ -67,14 +70,16 @@ | ||||||
|         ✔ Mutex @done(19-08-13 16:43) |         ✔ Mutex @done(19-08-13 16:43) | ||||||
|         ✔ Object @done(19-08-13 15:41) |         ✔ Object @done(19-08-13 15:41) | ||||||
|         ✔ Process @started(19-08-13 16:43) @done(19-12-22 18:41) |         ✔ Process @started(19-08-13 16:43) @done(19-12-22 18:41) | ||||||
|         ☐ Code set @started(19-12-22 18:41) |         ✔ Code set @started(19-12-22 18:41) @done(20-01-03 15:15) @lasted(1w4d20h34m2s) | ||||||
|             Needs a way to reference loaded images (so we don't serialize the entire ROM as well) |             Needs a way to reference loaded images (so we don't serialize the entire ROM as well) | ||||||
|  |             ☐ Serialize codeset with an apploader reference instead | ||||||
|         ✔ Resource limit @done(19-08-13 16:43) |         ✔ Resource limit @done(19-08-13 16:43) | ||||||
|         ✔ Semaphore @done(19-08-13 16:44) |         ✔ Semaphore @done(19-08-13 16:44) | ||||||
|         ✔ Server port @done(19-08-13 16:44) |         ✔ Server port @done(19-08-13 16:44) | ||||||
|         ✔ Server session @done(19-08-13 16:44) |         ✔ Server session @done(19-08-13 16:44) | ||||||
|             ☐ Mapped buffer context |             ✔ Mapped buffer context @done(20-01-03 15:25) | ||||||
|                 This may not be needed! |                 This is needed because IPC can take as long as it takes | ||||||
|  |                 Changed the unique_ptr<u8[]> to vector<u8> | ||||||
|         ✔ Session @done(19-08-13 16:44) |         ✔ Session @done(19-08-13 16:44) | ||||||
|         ☐ Shared memory @started(19-12-22 21:20) |         ☐ Shared memory @started(19-12-22 21:20) | ||||||
|             Need to figure out backing memory (a u8*) |             Need to figure out backing memory (a u8*) | ||||||
|  |  | ||||||
|  | @ -3,6 +3,7 @@ | ||||||
| // Refer to the license.txt file included.
 | // Refer to the license.txt file included.
 | ||||||
| 
 | 
 | ||||||
| #include <clocale> | #include <clocale> | ||||||
|  | #include <fstream> | ||||||
| #include <memory> | #include <memory> | ||||||
| #include <thread> | #include <thread> | ||||||
| #include <QDesktopWidget> | #include <QDesktopWidget> | ||||||
|  | @ -606,6 +607,8 @@ void GMainWindow::ConnectMenuEvents() { | ||||||
|             &GMainWindow::OnMenuReportCompatibility); |             &GMainWindow::OnMenuReportCompatibility); | ||||||
|     connect(ui.action_Configure, &QAction::triggered, this, &GMainWindow::OnConfigure); |     connect(ui.action_Configure, &QAction::triggered, this, &GMainWindow::OnConfigure); | ||||||
|     connect(ui.action_Cheats, &QAction::triggered, this, &GMainWindow::OnCheats); |     connect(ui.action_Cheats, &QAction::triggered, this, &GMainWindow::OnCheats); | ||||||
|  |     connect(ui.action_Save, &QAction::triggered, this, &GMainWindow::OnSave); | ||||||
|  |     connect(ui.action_Load, &QAction::triggered, this, &GMainWindow::OnLoad); | ||||||
| 
 | 
 | ||||||
|     // View
 |     // View
 | ||||||
|     connect(ui.action_Single_Window_Mode, &QAction::triggered, this, |     connect(ui.action_Single_Window_Mode, &QAction::triggered, this, | ||||||
|  | @ -1033,6 +1036,8 @@ void GMainWindow::ShutdownGame() { | ||||||
|     ui.action_Stop->setEnabled(false); |     ui.action_Stop->setEnabled(false); | ||||||
|     ui.action_Restart->setEnabled(false); |     ui.action_Restart->setEnabled(false); | ||||||
|     ui.action_Cheats->setEnabled(false); |     ui.action_Cheats->setEnabled(false); | ||||||
|  |     ui.action_Save->setEnabled(false); | ||||||
|  |     ui.action_Load->setEnabled(false); | ||||||
|     ui.action_Load_Amiibo->setEnabled(false); |     ui.action_Load_Amiibo->setEnabled(false); | ||||||
|     ui.action_Remove_Amiibo->setEnabled(false); |     ui.action_Remove_Amiibo->setEnabled(false); | ||||||
|     ui.action_Report_Compatibility->setEnabled(false); |     ui.action_Report_Compatibility->setEnabled(false); | ||||||
|  | @ -1343,6 +1348,8 @@ void GMainWindow::OnStartGame() { | ||||||
|     ui.action_Stop->setEnabled(true); |     ui.action_Stop->setEnabled(true); | ||||||
|     ui.action_Restart->setEnabled(true); |     ui.action_Restart->setEnabled(true); | ||||||
|     ui.action_Cheats->setEnabled(true); |     ui.action_Cheats->setEnabled(true); | ||||||
|  |     ui.action_Save->setEnabled(true); | ||||||
|  |     ui.action_Load->setEnabled(true); | ||||||
|     ui.action_Load_Amiibo->setEnabled(true); |     ui.action_Load_Amiibo->setEnabled(true); | ||||||
|     ui.action_Report_Compatibility->setEnabled(true); |     ui.action_Report_Compatibility->setEnabled(true); | ||||||
|     ui.action_Enable_Frame_Advancing->setEnabled(true); |     ui.action_Enable_Frame_Advancing->setEnabled(true); | ||||||
|  | @ -1496,6 +1503,23 @@ void GMainWindow::OnCheats() { | ||||||
|     cheat_dialog.exec(); |     cheat_dialog.exec(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void GMainWindow::OnSave() { | ||||||
|  |     Core::System& system{Core::System::GetInstance()}; | ||||||
|  |     auto fs = std::ofstream("save0.citrasave"); | ||||||
|  |     emu_thread->SetRunning(false); | ||||||
|  |     Core::System::GetInstance().Save(fs); | ||||||
|  |     emu_thread->SetRunning(true); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | void GMainWindow::OnLoad() { | ||||||
|  |     if (QFileInfo("save0.citrasave").exists()) { | ||||||
|  |         auto fs = std::ifstream("save0.citrasave"); | ||||||
|  |         emu_thread->SetRunning(false); | ||||||
|  |         Core::System::GetInstance().Load(fs); | ||||||
|  |         emu_thread->SetRunning(true); | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| void GMainWindow::OnConfigure() { | void GMainWindow::OnConfigure() { | ||||||
|     ConfigureDialog configureDialog(this, hotkey_registry, |     ConfigureDialog configureDialog(this, hotkey_registry, | ||||||
|                                     !multiplayer_state->IsHostingPublicRoom()); |                                     !multiplayer_state->IsHostingPublicRoom()); | ||||||
|  |  | ||||||
|  | @ -163,6 +163,8 @@ private slots: | ||||||
|     void OnStartGame(); |     void OnStartGame(); | ||||||
|     void OnPauseGame(); |     void OnPauseGame(); | ||||||
|     void OnStopGame(); |     void OnStopGame(); | ||||||
|  |     void OnSave(); | ||||||
|  |     void OnLoad(); | ||||||
|     void OnMenuReportCompatibility(); |     void OnMenuReportCompatibility(); | ||||||
|     /// Called whenever a user selects a game in the game list widget.
 |     /// Called whenever a user selects a game in the game list widget.
 | ||||||
|     void OnGameListLoadFile(QString game_path); |     void OnGameListLoadFile(QString game_path); | ||||||
|  |  | ||||||
|  | @ -88,6 +88,8 @@ | ||||||
|     <addaction name="separator"/> |     <addaction name="separator"/> | ||||||
|     <addaction name="action_Configure"/> |     <addaction name="action_Configure"/> | ||||||
|     <addaction name="action_Cheats"/> |     <addaction name="action_Cheats"/> | ||||||
|  |     <addaction name="action_Save"/> | ||||||
|  |     <addaction name="action_Load"/> | ||||||
|    </widget> |    </widget> | ||||||
|    <widget class="QMenu" name="menu_View"> |    <widget class="QMenu" name="menu_View"> | ||||||
|     <property name="title"> |     <property name="title"> | ||||||
|  | @ -217,6 +219,22 @@ | ||||||
|     <string>&Stop</string> |     <string>&Stop</string> | ||||||
|    </property> |    </property> | ||||||
|   </action> |   </action> | ||||||
|  |   <action name="action_Save"> | ||||||
|  |     <property name="enabled"> | ||||||
|  |       <bool>false</bool> | ||||||
|  |     </property> | ||||||
|  |     <property name="text"> | ||||||
|  |       <string>Save</string> | ||||||
|  |     </property> | ||||||
|  |   </action> | ||||||
|  |   <action name="action_Load"> | ||||||
|  |     <property name="enabled"> | ||||||
|  |       <bool>false</bool> | ||||||
|  |     </property> | ||||||
|  |     <property name="text"> | ||||||
|  |       <string>Load</string> | ||||||
|  |     </property> | ||||||
|  |   </action> | ||||||
|   <action name="action_FAQ"> |   <action name="action_FAQ"> | ||||||
|    <property name="text"> |    <property name="text"> | ||||||
|     <string>FAQ</string> |     <string>FAQ</string> | ||||||
|  |  | ||||||
|  | @ -86,7 +86,6 @@ add_library(common STATIC | ||||||
|     misc.cpp |     misc.cpp | ||||||
|     param_package.cpp |     param_package.cpp | ||||||
|     param_package.h |     param_package.h | ||||||
|     pod.h |  | ||||||
|     quaternion.h |     quaternion.h | ||||||
|     ring_buffer.h |     ring_buffer.h | ||||||
|     scm_rev.cpp |     scm_rev.cpp | ||||||
|  |  | ||||||
|  | @ -61,8 +61,7 @@ private: | ||||||
|     friend class boost::serialization::access; |     friend class boost::serialization::access; | ||||||
|     template <class Archive> |     template <class Archive> | ||||||
|     void serialize(Archive& ar, const unsigned int file_version) { |     void serialize(Archive& ar, const unsigned int file_version) { | ||||||
|         auto o_config_mem = boost::serialization::binary_object(&config_mem, sizeof(config_mem)); |         ar& boost::serialization::make_binary_object(&config_mem, sizeof(config_mem)); | ||||||
|         ar& o_config_mem; |  | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -193,19 +193,19 @@ ResultCode TranslateCommandBuffer(Kernel::KernelSystem& kernel, Memory::MemorySy | ||||||
|             // TODO(Subv): Perform permission checks.
 |             // TODO(Subv): Perform permission checks.
 | ||||||
| 
 | 
 | ||||||
|             // Reserve a page of memory before the mapped buffer
 |             // Reserve a page of memory before the mapped buffer
 | ||||||
|             auto reserve_buffer = std::make_unique<u8[]>(Memory::PAGE_SIZE); |             auto reserve_buffer = std::vector<u8>(Memory::PAGE_SIZE); | ||||||
|             dst_process->vm_manager.MapBackingMemoryToBase( |             dst_process->vm_manager.MapBackingMemoryToBase( | ||||||
|                 Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, reserve_buffer.get(), |                 Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, reserve_buffer.data(), | ||||||
|                 Memory::PAGE_SIZE, Kernel::MemoryState::Reserved); |                 Memory::PAGE_SIZE, Kernel::MemoryState::Reserved); | ||||||
| 
 | 
 | ||||||
|             auto buffer = std::make_unique<u8[]>(num_pages * Memory::PAGE_SIZE); |             auto buffer = std::vector<u8>(num_pages * Memory::PAGE_SIZE); | ||||||
|             memory.ReadBlock(*src_process, source_address, buffer.get() + page_offset, size); |             memory.ReadBlock(*src_process, source_address, buffer.data() + page_offset, size); | ||||||
| 
 | 
 | ||||||
|             // Map the page(s) into the target process' address space.
 |             // Map the page(s) into the target process' address space.
 | ||||||
|             target_address = |             target_address = | ||||||
|                 dst_process->vm_manager |                 dst_process->vm_manager | ||||||
|                     .MapBackingMemoryToBase(Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, |                     .MapBackingMemoryToBase(Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, | ||||||
|                                             buffer.get(), num_pages * Memory::PAGE_SIZE, |                                             buffer.data(), num_pages * Memory::PAGE_SIZE, | ||||||
|                                             Kernel::MemoryState::Shared) |                                             Kernel::MemoryState::Shared) | ||||||
|                     .Unwrap(); |                     .Unwrap(); | ||||||
| 
 | 
 | ||||||
|  | @ -213,7 +213,7 @@ ResultCode TranslateCommandBuffer(Kernel::KernelSystem& kernel, Memory::MemorySy | ||||||
| 
 | 
 | ||||||
|             // Reserve a page of memory after the mapped buffer
 |             // Reserve a page of memory after the mapped buffer
 | ||||||
|             dst_process->vm_manager.MapBackingMemoryToBase( |             dst_process->vm_manager.MapBackingMemoryToBase( | ||||||
|                 Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, reserve_buffer.get(), |                 Memory::IPC_MAPPING_VADDR, Memory::IPC_MAPPING_SIZE, reserve_buffer.data(), | ||||||
|                 Memory::PAGE_SIZE, Kernel::MemoryState::Reserved); |                 Memory::PAGE_SIZE, Kernel::MemoryState::Reserved); | ||||||
| 
 | 
 | ||||||
|             mapped_buffer_context.push_back({permissions, size, source_address, |             mapped_buffer_context.push_back({permissions, size, source_address, | ||||||
|  |  | ||||||
|  | @ -6,7 +6,7 @@ | ||||||
| 
 | 
 | ||||||
| #include <memory> | #include <memory> | ||||||
| #include <vector> | #include <vector> | ||||||
| #include <boost/serialization/unique_ptr.hpp> | #include <boost/serialization/vector.hpp> | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
| #include "core/hle/ipc.h" | #include "core/hle/ipc.h" | ||||||
| #include "core/hle/kernel/thread.h" | #include "core/hle/kernel/thread.h" | ||||||
|  | @ -25,8 +25,8 @@ struct MappedBufferContext { | ||||||
|     VAddr source_address; |     VAddr source_address; | ||||||
|     VAddr target_address; |     VAddr target_address; | ||||||
| 
 | 
 | ||||||
|     std::unique_ptr<u8[]> buffer; |     std::vector<u8> buffer; | ||||||
|     std::unique_ptr<u8[]> reserve_buffer; |     std::vector<u8> reserve_buffer; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|     template <class Archive> |     template <class Archive> | ||||||
|  | @ -35,10 +35,8 @@ private: | ||||||
|         ar& size; |         ar& size; | ||||||
|         ar& source_address; |         ar& source_address; | ||||||
|         ar& target_address; |         ar& target_address; | ||||||
|         // TODO: Check whether we need these. If we do, add a field for the size and/or change to a
 |         ar& buffer; | ||||||
|         // 'vector'
 |         ar& reserve_buffer; | ||||||
|         // ar & buffer;
 |  | ||||||
|         // ar & reserve_buffer;
 |  | ||||||
|     } |     } | ||||||
|     friend class boost::serialization::access; |     friend class boost::serialization::access; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -29,7 +29,7 @@ template <class Archive> | ||||||
| void Process::serialize(Archive& ar, const unsigned int file_version) { | void Process::serialize(Archive& ar, const unsigned int file_version) { | ||||||
|     ar& boost::serialization::base_object<Object>(*this); |     ar& boost::serialization::base_object<Object>(*this); | ||||||
|     ar& handle_table; |     ar& handle_table; | ||||||
|     ar& codeset; |     ar& codeset; // TODO: Replace with apploader reference
 | ||||||
|     ar& resource_limit; |     ar& resource_limit; | ||||||
|     ar& svc_access_mask; |     ar& svc_access_mask; | ||||||
|     ar& handle_table_size; |     ar& handle_table_size; | ||||||
|  |  | ||||||
|  | @ -133,7 +133,7 @@ private: | ||||||
|     template <class Archive> |     template <class Archive> | ||||||
|     void serialize(Archive& ar, const unsigned int file_version) { |     void serialize(Archive& ar, const unsigned int file_version) { | ||||||
|         ar& boost::serialization::base_object<Object>(*this); |         ar& boost::serialization::base_object<Object>(*this); | ||||||
|         // TODO: memory reference
 |         ar& memory; | ||||||
|         ar& segments; |         ar& segments; | ||||||
|         ar& entrypoint; |         ar& entrypoint; | ||||||
|         ar& name; |         ar& name; | ||||||
|  |  | ||||||
|  | @ -301,8 +301,7 @@ private: | ||||||
| 
 | 
 | ||||||
|     template <class Archive> |     template <class Archive> | ||||||
|     void serialize(Archive& ar, const unsigned int) { |     void serialize(Archive& ar, const unsigned int) { | ||||||
|         auto obj = boost::serialization::binary_object(this, sizeof(Regs)); |         ar& boost::serialization::make_binary_object(this, sizeof(Regs)); | ||||||
|         ar& obj; |  | ||||||
|     } |     } | ||||||
|     friend class boost::serialization::access; |     friend class boost::serialization::access; | ||||||
| }; | }; | ||||||
|  |  | ||||||
|  | @ -84,18 +84,15 @@ private: | ||||||
|     friend class boost::serialization::access; |     friend class boost::serialization::access; | ||||||
|     template <class Archive> |     template <class Archive> | ||||||
|     void serialize(Archive& ar, const unsigned int file_version) { |     void serialize(Archive& ar, const unsigned int file_version) { | ||||||
|         // TODO: Skip n3ds ram when not used?
 |         ar& boost::serialization::make_binary_object(fcram.get(), Memory::FCRAM_N3DS_SIZE); | ||||||
|         auto s_fcram = boost::serialization::binary_object(fcram.get(), Memory::FCRAM_N3DS_SIZE); |         ar& boost::serialization::make_binary_object(vram.get(), Memory::VRAM_SIZE); | ||||||
|         auto s_vram = boost::serialization::binary_object(vram.get(), Memory::VRAM_SIZE); |         // TODO: When n3ds support is added, put this back in
 | ||||||
|         auto s_extra = |         // ar& boost::serialization::make_binary_object(n3ds_extra_ram.get(),
 | ||||||
|             boost::serialization::binary_object(n3ds_extra_ram.get(), Memory::N3DS_EXTRA_RAM_SIZE); |         //                                              Memory::N3DS_EXTRA_RAM_SIZE);
 | ||||||
|         ar& s_fcram; |         ar& current_page_table; | ||||||
|         ar& s_vram; |  | ||||||
|         ar& s_extra; |  | ||||||
|         ar& cache_marker; |         ar& cache_marker; | ||||||
|         // TODO: How the hell to do page tables..
 |         ar& page_table_list; | ||||||
|         // ar & page_table_list;
 |         // dsp is set from Core::System at startup
 | ||||||
|         // ar & current_page_table;
 |  | ||||||
|     } |     } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -9,7 +9,9 @@ | ||||||
| #include <memory> | #include <memory> | ||||||
| #include <string> | #include <string> | ||||||
| #include <vector> | #include <vector> | ||||||
| #include "boost/serialization/access.hpp" | #include <boost/serialization/access.hpp> | ||||||
|  | #include <boost/serialization/array.hpp> | ||||||
|  | #include <boost/serialization/vector.hpp> | ||||||
| #include "common/common_types.h" | #include "common/common_types.h" | ||||||
| #include "core/mmio.h" | #include "core/mmio.h" | ||||||
| 
 | 
 | ||||||
|  | @ -54,12 +56,14 @@ struct SpecialRegion { | ||||||
|     u32 size; |     u32 size; | ||||||
|     MMIORegionPointer handler; |     MMIORegionPointer handler; | ||||||
| 
 | 
 | ||||||
|  | private: | ||||||
|     template <class Archive> |     template <class Archive> | ||||||
|     void serialize(Archive& ar, const unsigned int file_version) { |     void serialize(Archive& ar, const unsigned int file_version) { | ||||||
|         ar& base; |         ar& base; | ||||||
|         ar& size; |         ar& size; | ||||||
|         ar& handler; |         ar& handler; | ||||||
|     } |     } | ||||||
|  |     friend class boost::serialization::access; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /**
 | /**
 | ||||||
|  | @ -86,6 +90,15 @@ struct PageTable { | ||||||
|      * the corresponding entry in `pointers` MUST be set to null. |      * the corresponding entry in `pointers` MUST be set to null. | ||||||
|      */ |      */ | ||||||
|     std::array<PageType, PAGE_TABLE_NUM_ENTRIES> attributes; |     std::array<PageType, PAGE_TABLE_NUM_ENTRIES> attributes; | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     template <class Archive> | ||||||
|  |     void serialize(Archive& ar, const unsigned int) { | ||||||
|  |         // TODO: Pointers; same as VMA backing regions we need to serialize the u8*
 | ||||||
|  |         ar& special_regions; | ||||||
|  |         ar& attributes; | ||||||
|  |     } | ||||||
|  |     friend class boost::serialization::access; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| /// Physical memory regions as seen from the ARM11
 | /// Physical memory regions as seen from the ARM11
 | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue