mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +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 | ||||
|     ✔ Basic version @done(20-01-03 15:27) | ||||
|     ☐ Multiple slots etc. | ||||
| ✔ CPU @done(19-08-13 15:41) | ||||
| ✔ Memory @done(19-08-13 15:41) | ||||
|     ☐ 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) | ||||
|     Memory only | ||||
| ✔ 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) | ||||
|         ✔ Object @done(19-08-13 15: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) | ||||
|             ☐ Serialize codeset with an apploader reference instead | ||||
|         ✔ Resource limit @done(19-08-13 16:43) | ||||
|         ✔ Semaphore @done(19-08-13 16:44) | ||||
|         ✔ Server port @done(19-08-13 16:44) | ||||
|         ✔ Server session @done(19-08-13 16:44) | ||||
|             ☐ Mapped buffer context | ||||
|                 This may not be needed! | ||||
|             ✔ Mapped buffer context @done(20-01-03 15:25) | ||||
|                 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) | ||||
|         ☐ Shared memory @started(19-12-22 21:20) | ||||
|             Need to figure out backing memory (a u8*) | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ | |||
| // Refer to the license.txt file included.
 | ||||
| 
 | ||||
| #include <clocale> | ||||
| #include <fstream> | ||||
| #include <memory> | ||||
| #include <thread> | ||||
| #include <QDesktopWidget> | ||||
|  | @ -606,6 +607,8 @@ void GMainWindow::ConnectMenuEvents() { | |||
|             &GMainWindow::OnMenuReportCompatibility); | ||||
|     connect(ui.action_Configure, &QAction::triggered, this, &GMainWindow::OnConfigure); | ||||
|     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
 | ||||
|     connect(ui.action_Single_Window_Mode, &QAction::triggered, this, | ||||
|  | @ -1033,6 +1036,8 @@ void GMainWindow::ShutdownGame() { | |||
|     ui.action_Stop->setEnabled(false); | ||||
|     ui.action_Restart->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_Remove_Amiibo->setEnabled(false); | ||||
|     ui.action_Report_Compatibility->setEnabled(false); | ||||
|  | @ -1343,6 +1348,8 @@ void GMainWindow::OnStartGame() { | |||
|     ui.action_Stop->setEnabled(true); | ||||
|     ui.action_Restart->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_Report_Compatibility->setEnabled(true); | ||||
|     ui.action_Enable_Frame_Advancing->setEnabled(true); | ||||
|  | @ -1496,6 +1503,23 @@ void GMainWindow::OnCheats() { | |||
|     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() { | ||||
|     ConfigureDialog configureDialog(this, hotkey_registry, | ||||
|                                     !multiplayer_state->IsHostingPublicRoom()); | ||||
|  |  | |||
|  | @ -163,6 +163,8 @@ private slots: | |||
|     void OnStartGame(); | ||||
|     void OnPauseGame(); | ||||
|     void OnStopGame(); | ||||
|     void OnSave(); | ||||
|     void OnLoad(); | ||||
|     void OnMenuReportCompatibility(); | ||||
|     /// Called whenever a user selects a game in the game list widget.
 | ||||
|     void OnGameListLoadFile(QString game_path); | ||||
|  |  | |||
|  | @ -88,6 +88,8 @@ | |||
|     <addaction name="separator"/> | ||||
|     <addaction name="action_Configure"/> | ||||
|     <addaction name="action_Cheats"/> | ||||
|     <addaction name="action_Save"/> | ||||
|     <addaction name="action_Load"/> | ||||
|    </widget> | ||||
|    <widget class="QMenu" name="menu_View"> | ||||
|     <property name="title"> | ||||
|  | @ -217,6 +219,22 @@ | |||
|     <string>&Stop</string> | ||||
|    </property> | ||||
|   </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"> | ||||
|    <property name="text"> | ||||
|     <string>FAQ</string> | ||||
|  |  | |||
|  | @ -86,7 +86,6 @@ add_library(common STATIC | |||
|     misc.cpp | ||||
|     param_package.cpp | ||||
|     param_package.h | ||||
|     pod.h | ||||
|     quaternion.h | ||||
|     ring_buffer.h | ||||
|     scm_rev.cpp | ||||
|  |  | |||
|  | @ -61,8 +61,7 @@ private: | |||
|     friend class boost::serialization::access; | ||||
|     template <class Archive> | ||||
|     void serialize(Archive& ar, const unsigned int file_version) { | ||||
|         auto o_config_mem = boost::serialization::binary_object(&config_mem, sizeof(config_mem)); | ||||
|         ar& o_config_mem; | ||||
|         ar& boost::serialization::make_binary_object(&config_mem, sizeof(config_mem)); | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -193,19 +193,19 @@ ResultCode TranslateCommandBuffer(Kernel::KernelSystem& kernel, Memory::MemorySy | |||
|             // TODO(Subv): Perform permission checks.
 | ||||
| 
 | ||||
|             // 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( | ||||
|                 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); | ||||
| 
 | ||||
|             auto buffer = std::make_unique<u8[]>(num_pages * Memory::PAGE_SIZE); | ||||
|             memory.ReadBlock(*src_process, source_address, buffer.get() + page_offset, size); | ||||
|             auto buffer = std::vector<u8>(num_pages * Memory::PAGE_SIZE); | ||||
|             memory.ReadBlock(*src_process, source_address, buffer.data() + page_offset, size); | ||||
| 
 | ||||
|             // Map the page(s) into the target process' address space.
 | ||||
|             target_address = | ||||
|                 dst_process->vm_manager | ||||
|                     .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) | ||||
|                     .Unwrap(); | ||||
| 
 | ||||
|  | @ -213,7 +213,7 @@ ResultCode TranslateCommandBuffer(Kernel::KernelSystem& kernel, Memory::MemorySy | |||
| 
 | ||||
|             // Reserve a page of memory after the mapped buffer
 | ||||
|             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); | ||||
| 
 | ||||
|             mapped_buffer_context.push_back({permissions, size, source_address, | ||||
|  |  | |||
|  | @ -6,7 +6,7 @@ | |||
| 
 | ||||
| #include <memory> | ||||
| #include <vector> | ||||
| #include <boost/serialization/unique_ptr.hpp> | ||||
| #include <boost/serialization/vector.hpp> | ||||
| #include "common/common_types.h" | ||||
| #include "core/hle/ipc.h" | ||||
| #include "core/hle/kernel/thread.h" | ||||
|  | @ -25,8 +25,8 @@ struct MappedBufferContext { | |||
|     VAddr source_address; | ||||
|     VAddr target_address; | ||||
| 
 | ||||
|     std::unique_ptr<u8[]> buffer; | ||||
|     std::unique_ptr<u8[]> reserve_buffer; | ||||
|     std::vector<u8> buffer; | ||||
|     std::vector<u8> reserve_buffer; | ||||
| 
 | ||||
| private: | ||||
|     template <class Archive> | ||||
|  | @ -35,10 +35,8 @@ private: | |||
|         ar& size; | ||||
|         ar& source_address; | ||||
|         ar& target_address; | ||||
|         // TODO: Check whether we need these. If we do, add a field for the size and/or change to a
 | ||||
|         // 'vector'
 | ||||
|         // ar & buffer;
 | ||||
|         // ar & reserve_buffer;
 | ||||
|         ar& buffer; | ||||
|         ar& reserve_buffer; | ||||
|     } | ||||
|     friend class boost::serialization::access; | ||||
| }; | ||||
|  |  | |||
|  | @ -29,7 +29,7 @@ template <class Archive> | |||
| void Process::serialize(Archive& ar, const unsigned int file_version) { | ||||
|     ar& boost::serialization::base_object<Object>(*this); | ||||
|     ar& handle_table; | ||||
|     ar& codeset; | ||||
|     ar& codeset; // TODO: Replace with apploader reference
 | ||||
|     ar& resource_limit; | ||||
|     ar& svc_access_mask; | ||||
|     ar& handle_table_size; | ||||
|  |  | |||
|  | @ -133,7 +133,7 @@ private: | |||
|     template <class Archive> | ||||
|     void serialize(Archive& ar, const unsigned int file_version) { | ||||
|         ar& boost::serialization::base_object<Object>(*this); | ||||
|         // TODO: memory reference
 | ||||
|         ar& memory; | ||||
|         ar& segments; | ||||
|         ar& entrypoint; | ||||
|         ar& name; | ||||
|  |  | |||
|  | @ -301,8 +301,7 @@ private: | |||
| 
 | ||||
|     template <class Archive> | ||||
|     void serialize(Archive& ar, const unsigned int) { | ||||
|         auto obj = boost::serialization::binary_object(this, sizeof(Regs)); | ||||
|         ar& obj; | ||||
|         ar& boost::serialization::make_binary_object(this, sizeof(Regs)); | ||||
|     } | ||||
|     friend class boost::serialization::access; | ||||
| }; | ||||
|  |  | |||
|  | @ -84,18 +84,15 @@ private: | |||
|     friend class boost::serialization::access; | ||||
|     template <class Archive> | ||||
|     void serialize(Archive& ar, const unsigned int file_version) { | ||||
|         // TODO: Skip n3ds ram when not used?
 | ||||
|         auto s_fcram = boost::serialization::binary_object(fcram.get(), Memory::FCRAM_N3DS_SIZE); | ||||
|         auto s_vram = boost::serialization::binary_object(vram.get(), Memory::VRAM_SIZE); | ||||
|         auto s_extra = | ||||
|             boost::serialization::binary_object(n3ds_extra_ram.get(), Memory::N3DS_EXTRA_RAM_SIZE); | ||||
|         ar& s_fcram; | ||||
|         ar& s_vram; | ||||
|         ar& s_extra; | ||||
|         ar& boost::serialization::make_binary_object(fcram.get(), Memory::FCRAM_N3DS_SIZE); | ||||
|         ar& boost::serialization::make_binary_object(vram.get(), Memory::VRAM_SIZE); | ||||
|         // TODO: When n3ds support is added, put this back in
 | ||||
|         // ar& boost::serialization::make_binary_object(n3ds_extra_ram.get(),
 | ||||
|         //                                              Memory::N3DS_EXTRA_RAM_SIZE);
 | ||||
|         ar& current_page_table; | ||||
|         ar& cache_marker; | ||||
|         // TODO: How the hell to do page tables..
 | ||||
|         // ar & page_table_list;
 | ||||
|         // ar & current_page_table;
 | ||||
|         ar& page_table_list; | ||||
|         // dsp is set from Core::System at startup
 | ||||
|     } | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -9,7 +9,9 @@ | |||
| #include <memory> | ||||
| #include <string> | ||||
| #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 "core/mmio.h" | ||||
| 
 | ||||
|  | @ -54,12 +56,14 @@ struct SpecialRegion { | |||
|     u32 size; | ||||
|     MMIORegionPointer handler; | ||||
| 
 | ||||
| private: | ||||
|     template <class Archive> | ||||
|     void serialize(Archive& ar, const unsigned int file_version) { | ||||
|         ar& base; | ||||
|         ar& size; | ||||
|         ar& handler; | ||||
|     } | ||||
|     friend class boost::serialization::access; | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  | @ -86,6 +90,15 @@ struct PageTable { | |||
|      * the corresponding entry in `pointers` MUST be set to null. | ||||
|      */ | ||||
|     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
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue