vault backup: 2025-04-20 14:00:47
This commit is contained in:
8
.obsidian/workspace.json
vendored
8
.obsidian/workspace.json
vendored
@@ -41,12 +41,12 @@
|
|||||||
"state": {
|
"state": {
|
||||||
"type": "markdown",
|
"type": "markdown",
|
||||||
"state": {
|
"state": {
|
||||||
"file": "PERSONAL PROJECTS/PS1 DOCS/PSX code logo show.md",
|
"file": "PERSONAL PROJECTS/PS1 DOCS/PSX code Gamepad code.md",
|
||||||
"mode": "source",
|
"mode": "source",
|
||||||
"source": false
|
"source": false
|
||||||
},
|
},
|
||||||
"icon": "lucide-file",
|
"icon": "lucide-file",
|
||||||
"title": "PSX code logo show"
|
"title": "PSX code Gamepad code"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -207,8 +207,9 @@
|
|||||||
},
|
},
|
||||||
"active": "dd912cc876184c4f",
|
"active": "dd912cc876184c4f",
|
||||||
"lastOpenFiles": [
|
"lastOpenFiles": [
|
||||||
"PERSONAL PROJECTS/PS1 DOCS/PSX code - Load texture from SECTOR!.md",
|
|
||||||
"PERSONAL PROJECTS/PS1 DOCS/PSX code logo show.md",
|
"PERSONAL PROJECTS/PS1 DOCS/PSX code logo show.md",
|
||||||
|
"PERSONAL PROJECTS/PS1 DOCS/PSX code Gamepad code.md",
|
||||||
|
"PERSONAL PROJECTS/PS1 DOCS/PSX code - Load texture from SECTOR!.md",
|
||||||
"WORK & PROJECTS/Mol/Code Chunks/TipTap Plugin.md",
|
"WORK & PROJECTS/Mol/Code Chunks/TipTap Plugin.md",
|
||||||
"PERSONAL PROJECTS/PS1 DOCS/PS1 Gamepad.md",
|
"PERSONAL PROJECTS/PS1 DOCS/PS1 Gamepad.md",
|
||||||
"PERSONAL PROJECTS/P2EP/pseudoCode/FUN_800453e0 SystemEventManager.md",
|
"PERSONAL PROJECTS/P2EP/pseudoCode/FUN_800453e0 SystemEventManager.md",
|
||||||
@@ -235,7 +236,6 @@
|
|||||||
"PERSONAL PROJECTS/PS1 DOCS/PS1 Vblank.md",
|
"PERSONAL PROJECTS/PS1 DOCS/PS1 Vblank.md",
|
||||||
"PERSONAL PROJECTS/PS1 DOCS/PS1 DMA CD-ROM.md",
|
"PERSONAL PROJECTS/PS1 DOCS/PS1 DMA CD-ROM.md",
|
||||||
"WORK & PROJECTS/Mol/Ideas/Все идеи для Моли.md",
|
"WORK & PROJECTS/Mol/Ideas/Все идеи для Моли.md",
|
||||||
"WORK & PROJECTS/Mol/Серверы/mail.mol-soft.ru.md",
|
|
||||||
"WORK & PROJECTS/Mol/Документы для ТЗ ЛИМС/СМК/КУ_Чек_лист_10_ошибок_УД_скачивание.pdf",
|
"WORK & PROJECTS/Mol/Документы для ТЗ ЛИМС/СМК/КУ_Чек_лист_10_ошибок_УД_скачивание.pdf",
|
||||||
"WORK & PROJECTS/Mol/Документы для ТЗ ЛИМС/СМК",
|
"WORK & PROJECTS/Mol/Документы для ТЗ ЛИМС/СМК",
|
||||||
"WORK & PROJECTS/Mol/Планы и диаграммы/00001_Редактор_форм/Таблицы нумератора и документов.canvas",
|
"WORK & PROJECTS/Mol/Планы и диаграммы/00001_Редактор_форм/Таблицы нумератора и документов.canvas",
|
||||||
|
|||||||
119
PERSONAL PROJECTS/PS1 DOCS/PSX code Gamepad code.md
Normal file
119
PERSONAL PROJECTS/PS1 DOCS/PSX code Gamepad code.md
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
|
||||||
|
Да, ваша структура `s_gamePad` вполне подходит для работы с геймпадами PlayStation 1, но требует некоторых доработок для корректной работы с PsyQ SDK. Вот полное решение:
|
||||||
|
|
||||||
|
### 1. Улучшенная структура геймпада
|
||||||
|
```c
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <psxpad.h>
|
||||||
|
|
||||||
|
#pragma pack(push, 1) // Выравнивание 1 байт
|
||||||
|
typedef struct {
|
||||||
|
uint8_t stat; // 0x00 - статус (0 = данные готовы)
|
||||||
|
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint8_t recvSize:4; // Размер полученных данных (4/8 байт)
|
||||||
|
uint8_t type:4; // Тип контроллера (4=Digital, 5=Analog)
|
||||||
|
};
|
||||||
|
uint8_t bConfig; // Объединение для удобства доступа
|
||||||
|
};
|
||||||
|
|
||||||
|
// Кнопки (битовая маска, 1=не нажата, 0=нажата)
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint16_t select:1; // 0x0001
|
||||||
|
uint16_t :1; // Не используется
|
||||||
|
uint16_t :1; // Не используется
|
||||||
|
uint16_t start:1; // 0x0008
|
||||||
|
uint16_t up:1; // 0x0010
|
||||||
|
uint16_t right:1; // 0x0020
|
||||||
|
uint16_t down:1; // 0x0040
|
||||||
|
uint16_t left:1; // 0x0080
|
||||||
|
uint16_t l2:1; // 0x0100
|
||||||
|
uint16_t r2:1; // 0x0200
|
||||||
|
uint16_t l1:1; // 0x0400
|
||||||
|
uint16_t r1:1; // 0x0800
|
||||||
|
uint16_t triangle:1; // 0x1000
|
||||||
|
uint16_t circle:1; // 0x2000
|
||||||
|
uint16_t cross:1; // 0x4000
|
||||||
|
uint16_t square:1; // 0x8000
|
||||||
|
};
|
||||||
|
uint16_t buttons; // Полное слово кнопок
|
||||||
|
};
|
||||||
|
|
||||||
|
// Аналоговые данные (для DualShock)
|
||||||
|
uint8_t rightJoyX; // 0x03 Правый джойстик X
|
||||||
|
uint8_t rightJoyY; // 0x04 Правый джойстик Y
|
||||||
|
uint8_t leftJoyX; // 0x05 Левый джойстик X
|
||||||
|
uint8_t leftJoyY; // 0x06 Левый джойстик Y
|
||||||
|
} s_gamePad;
|
||||||
|
#pragma pack(pop) // Восстановление выравнивания
|
||||||
|
|
||||||
|
static s_gamePad gamePads[2]; // Буферы для двух геймпадов
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Функция инициализации
|
||||||
|
```c
|
||||||
|
#define PAD_BUFFER_SIZE 34
|
||||||
|
|
||||||
|
void GamePadInit(void) {
|
||||||
|
static uint8_t padData[2][PAD_BUFFER_SIZE] __attribute__((aligned(64)));
|
||||||
|
|
||||||
|
// Инициализация буферов
|
||||||
|
PadInitDirect(padData[0], padData[1]);
|
||||||
|
|
||||||
|
// Начало опроса геймпадов
|
||||||
|
PadStartCom();
|
||||||
|
|
||||||
|
// Очистка структур
|
||||||
|
memset(gamePads, 0, sizeof(gamePads));
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Функция чтения состояния
|
||||||
|
```c
|
||||||
|
void GamePadRead(void) {
|
||||||
|
// Чтение сырых данных
|
||||||
|
uint8_t* padRaw = (uint8_t*)PadRead(0); // Чтение порта 0
|
||||||
|
|
||||||
|
// Копирование и преобразование данных
|
||||||
|
memcpy(&gamePads[0], padRaw, sizeof(s_gamePad));
|
||||||
|
|
||||||
|
// Инвертирование битов кнопок (в оригинале 1=не нажата)
|
||||||
|
gamePads[0].buttons ^= 0xFFFF;
|
||||||
|
|
||||||
|
// Аналогично для второго геймпада (порт 1)
|
||||||
|
padRaw = (uint8_t*)PadRead(1);
|
||||||
|
memcpy(&gamePads[1], padRaw, sizeof(s_gamePad));
|
||||||
|
gamePads[1].buttons ^= 0xFFFF;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Пример использования
|
||||||
|
```c
|
||||||
|
void Update(void) {
|
||||||
|
GamePadRead();
|
||||||
|
|
||||||
|
if (gamePads[0].cross) {
|
||||||
|
// Кнопка X нажата на первом геймпаде
|
||||||
|
}
|
||||||
|
|
||||||
|
if (gamePads[1].type == 5) { // Аналоговый геймпад
|
||||||
|
int stickX = gamePads[1].leftJoyX - 128; // -128..127
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ключевые особенности:
|
||||||
|
1. **Битовые поля** - Позволяют удобно обращаться к каждой кнопке
|
||||||
|
2. **Union** - Даёт доступ как к отдельным кнопкам, так и ко всему слову
|
||||||
|
3. **Аналоговые данные** - Поддержка DualShock
|
||||||
|
4. **Выравнивание** - `#pragma pack(push, 1)` гарантирует правильный layout структуры
|
||||||
|
5. **Инверсия битов** - В PS1 1=не нажато, поэтому делаем XOR
|
||||||
|
|
||||||
|
### Совместимость:
|
||||||
|
- Работает с Digital (SCPH-1080) и Analog (SCPH-1150) контроллерами
|
||||||
|
- Поддерживает DualShock (аналоговые стики)
|
||||||
|
- Корректно работает с PsyQ SDK 4.7 и новее
|
||||||
|
|
||||||
|
Такой подход более типобезопасен и удобен для чтения, чем оригинальный вариант с прямым доступом к памяти.
|
||||||
Reference in New Issue
Block a user