1 // Copyright (c) 2012- PPSSPP Project.
2 
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, version 2.0 or later versions.
6 
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 // GNU General Public License 2.0 for more details.
11 
12 // A copy of the GPL 2.0 should have been included with the program.
13 // If not, see http://www.gnu.org/licenses/
14 
15 // Official git repository and contact information can be found at
16 // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
17 
18 #include "Common/Serialize/Serializer.h"
19 #include "Common/Serialize/SerializeFuncs.h"
20 #include "Core/Dialog/PSPDialog.h"
21 #include "Core/Dialog/PSPScreenshotDialog.h"
22 #include "Core/HLE/sceKernel.h"
23 #include "Core/MemMap.h"
24 #include "Core/Reporting.h"
25 
26 enum SceUtilityScreenshotType {
27 	SCE_UTILITY_SCREENSHOT_TYPE_GUI = 0,
28 	SCE_UTILITY_SCREENSHOT_TYPE_AUTO = 1,
29 	SCE_UTILITY_SCREENSHOT_TYPE_SAVE = 2,
30 	SCE_UTILITY_SCREENSHOT_TYPE_VIEW = 3,
31 
32 	// Names are just guesses based on status value behavior.
33 	SCE_UTILITY_SCREENSHOT_TYPE_CONT_START = 100,
34 	SCE_UTILITY_SCREENSHOT_TYPE_CONT_FINISH = 101,
35 	SCE_UTILITY_SCREENSHOT_TYPE_CONT_STOP = 102,
36 };
37 
38 static const int SCE_UTILITY_SCREENSHOTDIALOG_SIZE_V1 = 436;
39 static const int SCE_UTILITY_SCREENSHOTDIALOG_SIZE_V2 = 928;
40 static const int SCE_UTILITY_SCREENSHOTDIALOG_SIZE_V3 = 932;
41 
42 #if COMMON_LITTLE_ENDIAN
43 typedef SceUtilityScreenshotType SceUtilityScreenshotType_le;
44 #else
45 typedef swap_struct_t<SceUtilityScreenshotType, swap_32_t<SceUtilityScreenshotType> > SceUtilityScreenshotType_le;
46 #endif
47 
48 struct SceUtilityScreenshotParams {
49 	pspUtilityDialogCommon base;
50 	SceUtilityScreenshotType_le mode;
51 
52 	// TODO
53 };
54 
PSPScreenshotDialog(UtilityDialogType type)55 PSPScreenshotDialog::PSPScreenshotDialog(UtilityDialogType type) : PSPDialog(type) {
56 }
57 
~PSPScreenshotDialog()58 PSPScreenshotDialog::~PSPScreenshotDialog() {
59 }
60 
Init(u32 paramAddr)61 int PSPScreenshotDialog::Init(u32 paramAddr) {
62 	// Already running
63 	if (ReadStatus() != SCE_UTILITY_STATUS_NONE && ReadStatus() != SCE_UTILITY_STATUS_SHUTDOWN) {
64 		ERROR_LOG_REPORT(HLE, "sceUtilityScreenshotInitStart(%08x): invalid status", paramAddr);
65 		return SCE_ERROR_UTILITY_INVALID_STATUS;
66 	}
67 
68 	params_ = PSPPointer<SceUtilityScreenshotParams>::Create(paramAddr);
69 	if (!params_.IsValid()) {
70 		ERROR_LOG_REPORT(HLE, "sceUtilityScreenshotInitStart(%08x): invalid pointer", paramAddr);
71 		return SCE_KERNEL_ERROR_INVALID_POINTER;
72 	}
73 
74 	switch ((u32)params_->base.size) {
75 	case SCE_UTILITY_SCREENSHOTDIALOG_SIZE_V1:
76 	case SCE_UTILITY_SCREENSHOTDIALOG_SIZE_V2:
77 	case SCE_UTILITY_SCREENSHOTDIALOG_SIZE_V3:
78 		break;
79 
80 	default:
81 		ERROR_LOG_REPORT(HLE, "sceUtilityScreenshotInitStart(%08x): invalid size %d", paramAddr, (u32)params_->base.size);
82 		return SCE_ERROR_UTILITY_INVALID_PARAM_SIZE;
83 	}
84 
85 	mode = params_->mode;
86 	ChangeStatus(SCE_UTILITY_STATUS_INITIALIZE, 0);
87 
88 	return 0;
89 }
90 
Update(int animSpeed)91 int PSPScreenshotDialog::Update(int animSpeed) {
92 	if (UseAutoStatus()) {
93 		if (ReadStatus() == SCE_UTILITY_STATUS_INITIALIZE) {
94 			ChangeStatus(SCE_UTILITY_STATUS_RUNNING, 0);
95 		} else if (ReadStatus() == SCE_UTILITY_STATUS_RUNNING) {
96 			if (mode == SCE_UTILITY_SCREENSHOT_TYPE_CONT_START) {
97 				ChangeStatus(SCE_UTILITY_STATUS_SCREENSHOT_UNKNOWN, 0);
98 			} else {
99 				ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0);
100 			}
101 		} else if (ReadStatus() == SCE_UTILITY_STATUS_FINISHED) {
102 			ChangeStatus(SCE_UTILITY_STATUS_SHUTDOWN, 0);
103 		}
104 	}
105 	return 0;
106 }
107 
ContStart()108 int PSPScreenshotDialog::ContStart() {
109 	// Based on JPCSP http://code.google.com/p/jpcsp/source/detail?r=3381
110 	if (ReadStatus() != SCE_UTILITY_STATUS_SCREENSHOT_UNKNOWN)
111 		return SCE_ERROR_UTILITY_INVALID_STATUS;
112 
113 	// Check with JPCSPTrace log of Dream Club Portable
114 	ChangeStatus(SCE_UTILITY_STATUS_FINISHED, 0);
115 
116 	return 0;
117 }
118 
DoState(PointerWrap & p)119 void PSPScreenshotDialog::DoState(PointerWrap &p) {
120 	PSPDialog::DoState(p);
121 
122 	auto s = p.Section("PSPScreenshotDialog", 0, 2);
123 	if (!s)
124 		return;
125 
126 	Do(p, mode);
127 	if (s >= 2) {
128 		Do(p, params_);
129 	}
130 }
131 
GetCommonParam()132 pspUtilityDialogCommon *PSPScreenshotDialog::GetCommonParam() {
133 	if (params_.IsValid())
134 		return &params_->base;
135 	return nullptr;
136 }
137