Seregon/ShadPKG

A tool for deriving PKG packet encryption keys for ps4 written in c++

C++/47.3 KB/No license
common/number_utils.cpp
ShadPKG / common / number_utils.cpp
1// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3 
4#include <array>
5#include <half.hpp>
6 
7#include "common/number_utils.h"
8#include "video_core/amdgpu/pixel_format.h"
9#include "video_core/amdgpu/types.h"
10 
11#define UF11_EXPONENT_SHIFT 6
12#define UF10_EXPONENT_SHIFT 5
13 
14#define RGB9E5_MANTISSA_BITS 9
15#define RGB9E5_EXP_BIAS 1
16 
17#define F32_INFINITY 0x7f800000
18 
19namespace NumberUtils {
20 
21float Uf11ToF32(u16 val) {
22 union {
23 float f;
24 u32 ui;
25 } f32;
26 
27 int exponent = (val & 0x07c0) >> UF11_EXPONENT_SHIFT;
28 int mantissa = (val & 0x003f);
29 
30 f32.f = 0.0;
31 
32 if (exponent == 0) {
33 if (mantissa != 0) {
34 const float scale = 1.0 / (1 << 20);
35 f32.f = scale * mantissa;
36 }
37 } else if (exponent == 31) {
38 f32.ui = F32_INFINITY | mantissa;
39 } else {
40 float scale, decimal;
41 exponent -= 15;
42 if (exponent < 0) {
43 scale = 1.0f / (1 << -exponent);
44 } else {
45 scale = (float)(1 << exponent);
46 }
47 decimal = 1.0f + (float)mantissa / 64;
48 f32.f = scale * decimal;
49 }
50 
51 return f32.f;
52}
53 
54float Uf10ToF32(u16 val) {
55 union {
56 float f;
57 u32 ui;
58 } f32;
59 
60 int exponent = (val & 0x03e0) >> UF10_EXPONENT_SHIFT;
61 int mantissa = (val & 0x001f);
62 
63 f32.f = 0.0;
64 
65 if (exponent == 0) {
66 if (mantissa != 0) {
67 const float scale = 1.0 / (1 << 19);
68 f32.f = scale * mantissa;
69 }
70 } else if (exponent == 31) {
71 f32.ui = F32_INFINITY | mantissa;
72 } else {
73 float scale, decimal;
74 exponent -= 15;
75 if (exponent < 0) {
76 scale = 1.0f / (1 << -exponent);
77 } else {
78 scale = (float)(1 << exponent);
79 }
80 decimal = 1.0f + (float)mantissa / 32;
81 f32.f = scale * decimal;
82 }
83 
84 return f32.f;
85}
86 
87float Uf16ToF32(u16 val) {
88 return half_float::half_cast<float>(reinterpret_cast<half_float::half&>(val));
89}
90 
91float U2ToUnorm(u8 val) {
92 static constexpr auto c = 1.0f / 3.0f;
93 return float(val * c);
94}
95 
96float S2ToSnorm(s8 val) {
97 static constexpr auto c = 1.0f / 1.0f;
98 return float(val * c);
99}
100 
101float U4ToUnorm(u8 val) {
102 static constexpr auto c = 1.0f / 15.0f;
103 return float(val * c);
104}
105 
106float S4ToSnorm(s8 val) {
107 static constexpr auto c = 1.0f / 7.0f;
108 return float(val * c);
109}
110 
111float U5ToUnorm(u8 val) {
112 static constexpr auto c = 1.0f / 31.0f;
113 return float(val * c);
114}
115 
116float S5ToSnorm(s8 val) {
117 static constexpr auto c = 1.0f / 15.0f;
118 return float(val * c);
119}
120 
121float U6ToUnorm(u8 val) {
122 static constexpr auto c = 1.0f / 63.0f;
123 return float(val * c);
124}
125 
126float S6ToSnorm(s8 val) {
127 static constexpr auto c = 1.0f / 31.0f;
128 return float(val * c);
129}
130 
131float U8ToUnorm(u8 val) {
132 static constexpr auto c = 1.0f / 255.0f;
133 return float(val * c);
134}
135 
136float S8ToSnorm(s8 val) {
137 static constexpr auto c = 1.0f / 127.0f;
138 return float(val * c);
139}
140 
141float U10ToUnorm(u16 val) {
142 static constexpr auto c = 1.0f / 1023.0f;
143 return float(val * c);
144}
145 
146float S10ToSnorm(s16 val) {
147 static constexpr auto c = 1.0f / 511.0f;
148 return float(val * c);
149}
150 
151float U16ToUnorm(u16 val) {
152 static constexpr auto c = 1.0f / 65535.0f;
153 return float(val * c);
154}
155 
156float S16ToSnorm(s16 val) {
157 static constexpr auto c = 1.0f / 32767.0f;
158 return float(val * c);
159}
160 
161} // namespace NumberUtils