- [FIX] estaven mal els opcodes LDH i els nous ADD sp,e8 i LD hl,sp+e8

- [NEW] Modul sm83dis per a mostrar el desensamblat del codi completat
- [NEW] Afegits moduls ui, ui_menu i ui_window, i el font.bmp, quasi tal qual des del projecte z80
This commit is contained in:
2025-01-15 11:18:58 +01:00
parent 0c97143b22
commit b06f26a4b7
10 changed files with 536 additions and 6 deletions

BIN
font.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@@ -967,15 +967,15 @@ namespace sm83
case 0xDE: SBC8(READ_MEM_8()); break;
case 0xDF: RST(0x18); break;
case 0xE0: WRITE_MEM_8(READ_MEM_8()|0x00ff, rA);break;
case 0xE0: WRITE_MEM_8(READ_MEM_8()|0xff00, rA);break;
case 0xE1: POP(_rHL); break;
case 0xE2: WRITE_MEM_8(rC|0x00ff, rA); break;
case 0xE2: WRITE_MEM_8(rC|0xff00, rA); break;
case 0xE3: IgnoreOpcode(); break;
case 0xE4: IgnoreOpcode(); break;
case 0xE5: PUSH(rHL); break;
case 0xE6: AND(READ_MEM_8()); break;
case 0xE7: RST(0x20); break;
case 0xE8: ADD16(_rSP, READ_MEM_8()); break; /*[TODO] es correcte? ha de ser signed*/
case 0xE8: ADD16(_rSP, (int8_t)READ_MEM_8());break; /*[TODO] es correcte? ha de ser signed*/
case 0xE9: JP(cUnconditional, rHL, true); break;
case 0xEA: WRITE_MEM_8(READ_MEM_16(), rA); break;
case 0xEB: IgnoreOpcode(); break;
@@ -984,15 +984,15 @@ namespace sm83
case 0xEE: XOR(READ_MEM_8()); break;
case 0xEF: RST(0x28); break;
case 0xF0: rA = READ_MEM_8(READ_MEM_8()|0x00ff);break;
case 0xF0: rA = READ_MEM_8(READ_MEM_8()|0xff00);break;
case 0xF1: POP(_rAF); break;
case 0xF2: rA = READ_MEM_8(rC|0x00ff); break;
case 0xF2: rA = READ_MEM_8(rC|0xff00); break;
case 0xF3: DI(); break;
case 0xF4: IgnoreOpcode(); break;
case 0xF5: PUSH(rAF); break;
case 0xF6: OR(READ_MEM_8()); break;
case 0xF7: RST(0x30); break;
case 0xF8: rHL = rSP + READ_MEM_8(); break; /*[TODO] es correcte? ha de ser signed*/
case 0xF8: rHL = rSP + (int8_t)READ_MEM_8();break; /*[TODO] es correcte? ha de ser signed*/
case 0xF9: rSP = rHL; t+=2; break;
case 0xFA: rA = READ_MEM_8(READ_MEM_16()); break;
case 0xFB: EI(); break;

172
sm83dis.cpp Normal file
View File

@@ -0,0 +1,172 @@
#include "sm83dis.h"
#include "sm83.h"
#include "mem.h"
#include <string.h>
#include <stdio.h>
#include <vector>
#include <bits/stdc++.h>
namespace sm83dis
{
char buffer[256];
int opcode_size = 0;
char symbols[65536][15];
std::vector<uint16_t> used_symbols;
// $%04x
// $%02x
// %hhd
const char *base_opcodes[256] = {"nop", "ld bc,$%04x", "ld (bc),a", "inc bc", "inc b", "dec b", "ld b,$%02x", "rlca", "ld ($%04x), sp", "add hl,bc", "ld a,(bc)", "dec bc", "inc c", "dec c", "ld c,$%02x", "rrca", "stop $%02x", "ld de,$%04x", "ld (de),a", "inc de", "inc d", "dec d", "ld d,$%02x", "rla", "jr $%Xx", "add hl,de", "ld a,(de)", "dec de", "inc e", "dec e", "ld e,$%02x", "rra", "jr nz,$%Xx", "ld hl,$%04x", "ld (hl+),a", "inc hl", "inc h", "dec h", "ld h,$%02x", "daa", "jr z,$%Xx", "add hl,hl", "ld a, (hl+)", "dec hl", "inc l", "dec l", "ld l,$%02x", "cpl", "jr nc,$%Xx", "ld sp,$%04x", "ld (hl-),a", "inc sp", "inc (hl)", "dec (hl)", "ld (hl),$%02x", "scf", "jr c,$%Xx", "add hl,sp", "ld a,(hl-)", "dec sp", "inc a", "dec a", "ld a,$%02x", "ccf", "ld b,b", "ld b,c", "ld b,d", "ld b,e", "ld b,h", "ld b,l", "ld b,(hl)", "ld b,a", "ld c,b", "ld c,c", "ld c,d", "ld c,e", "ld c,h", "ld c,l", "ld c,(hl)", "ld c,a", "ld d,b", "ld d,c", "ld d,d", "ld d,e", "ld d,h", "ld d,l", "ld d,(hl)", "ld d,a", "ld e,b", "ld e,c", "ld e,d", "ld e,e", "ld e,h", "ld e,l", "ld e,(hl)", "ld e,a", "ld h,b", "ld h,c", "ld h,d", "ld h,e", "ld h,h", "ld h,l", "ld h,(hl)", "ld h,a", "ld l,b", "ld l,c", "ld l,d", "ld l,e", "ld l,h", "ld l,l", "ld l,(hl)", "ld l,a", "ld (hl),b", "ld (hl),c", "ld (hl),d", "ld (hl),e", "ld (hl),h", "ld (hl),l", "halt", "ld (hl),a", "ld a,b", "ld a,c", "ld a,d", "ld a,e", "ld a,h", "ld a,l", "ld a,(hl)", "ld a,a", "add a,b", "add a,c", "add a,d", "add a,e", "add a,h", "add a,l", "add a,(hl)", "add a,a", "adc a,b", "adc a,c", "adc a,d", "adc a,e", "adc a,h", "adc a,l", "adc a,(hl)", "adc a,a", "sub b", "sub c", "sub d", "sub e", "sub h", "sub l", "sub (hl)", "sub a", "sbc a,b", "sbc a,c", "sbc a,d", "sbc a,e", "sbc a,h", "sbc a,l", "sbc a,(hl)", "sbc a,a", "and b", "and c", "and d", "and e", "and h", "and l", "and (hl)", "and a", "xor b", "xor c", "xor d", "xor e", "xor h", "xor l", "xor (hl)", "xor a", "or b", "or c", "or d", "or e", "or h", "or l", "or (hl)", "or a", "cp b", "cp c", "cp d", "cp e", "cp h", "cp l", "cp (hl)", "cp a", "ret nz", "pop bc", "jp nz,$%04x", "jp $%04x", "call nz,$%04x", "push bc", "add a,$%02x", "rst &00", "ret z", "ret", "jp z,$%04x", "_Bit_", "call z,$%04x", "call $%04x", "adc a,$%02x", "rst $08", "ret nc", "pop de", "jp nc,$%04x", "---", "call nc,$%04x", "push de", "sub a,$%02x", "rst $10", "ret c", "reti", "jp c,$%04x", "---", "call c,$%04x", "---", "sbc a,$%02x", "rst $18", "ldh ($%02x),a", "pop hl", "ldh (c),a", "---", "---", "push hl", "and a,$%02x", "rst $20", "add sp,$%Xx", "jp hl", "ld ($%04x),a", "---", "---", "---", "xor a,$%02x", "rst $28", "ldh a,($%02x)", "pop af", "ld a,(c)", "di", "---", "push af", "or a,$%02x", "rst $30", "ld hl,sp+$%Xx", "ld sp,hl", "ld a,($%04x)", "ei", "---", "---", "cp a,$%02x", "rst $38"};
const char *bit_opcodes[256] = {"rlc b", "rlc c", "rlc d", "rlc e", "rlc h", "rlc l", "rlc (hl)", "rlc a", "rrc b", "rrc c", "rrc d", "rrc e", "rrc h", "rrc l", "rrc (hl)", "rrc a", "rl b", "rl c", "rl d", "rl e", "rl h", "rl l", "rl (hl)", "rl a", "rr b", "rr c", "rr d", "rr e", "rr h", "rr l", "rr (hl)", "rr a", "sla b", "sla c", "sla d", "sla e", "sla h", "sla l", "sla (hl)", "sla a", "sra b", "sra c", "sra d", "sra e", "sra h", "sra l", "sra (hl)", "sra a", "swap b", "swap c", "swap d", "swap e", "swap h", "swap l", "swap (hl)", "swap a", "srl b", "srl c", "srl d", "srl e", "srl h", "srl l", "srl (hl)", "srl a", "bit 0,b", "bit 0,c", "bit 0,d", "bit 0,e", "bit 0,h", "bit 0,l", "bit 0,(hl)", "bit 0,a", "bit 1,b", "bit 1,c", "bit 1,d", "bit 1,e", "bit 1,h", "bit 1,l", "bit 1,(hl)", "bit 1,a", "bit 2,b", "bit 2,c", "bit 2,d", "bit 2,e", "bit 2,h", "bit 2,l", "bit 2,(hl)", "bit 2,a", "bit 3,b", "bit 3,c", "bit 3,d", "bit 3,e", "bit 3,h", "bit 3,l", "bit 3,(hl)", "bit 3,a", "bit 4,b", "bit 4,c", "bit 4,d", "bit 4,e", "bit 4,h", "bit 4,l", "bit 4,(hl)", "bit 4,a", "bit 5,b", "bit 5,c", "bit 5,d", "bit 5,e", "bit 5,h", "bit 5,l", "bit 5,(hl)", "bit 5,a", "bit 6,b", "bit 6,c", "bit 6,d", "bit 6,e", "bit 6,h", "bit 6,l", "bit 6,(hl)", "bit 6,a", "bit 7,b", "bit 7,c", "bit 7,d", "bit 7,e", "bit 7,h", "bit 7,l", "bit 7,(hl)", "bit 7,a", "res 0,b", "res 0,c", "res 0,d", "res 0,e", "res 0,h", "res 0,l", "res 0,(hl)", "res 0,a", "res 1,b", "res 1,c", "res 1,d", "res 1,e", "res 1,h", "res 1,l", "res 1,(hl)", "res 1,a", "res 2,b", "res 2,c", "res 2,d", "res 2,e", "res 2,h", "res 2,l", "res 2,(hl)", "res 2,a", "res 3,b", "res 3,c", "res 3,d", "res 3,e", "res 3,h", "res 3,l", "res 3,(hl)", "res 3,a", "res 4,b", "res 4,c", "res 4,d", "res 4,e", "res 4,h", "res 4,l", "res 4,(hl)", "res 4,a", "res 5,b", "res 5,c", "res 5,d", "res 5,e", "res 5,h", "res 5,l", "res 5,(hl)", "res 5,a", "res 6,b", "res 6,c", "res 6,d", "res 6,e", "res 6,h", "res 6,l", "res 6,(hl)", "res 6,a", "res 7,b", "res 7,c", "res 7,d", "res 7,e", "res 7,h", "res 7,l", "res 7,(hl)", "res 7,a", "set 0,b", "set 0,c", "set 0,d", "set 0,e", "set 0,h", "set 0,l", "set 0,(hl)", "set 0,a", "set 1,b", "set 1,c", "set 1,d", "set 1,e", "set 1,h", "set 1,l", "set 1,(hl)", "set 1,a", "set 2,b", "set 2,c", "set 2,d", "set 2,e", "set 2,h", "set 2,l", "set 2,(hl)", "set 2,a", "set 3,b", "set 3,c", "set 3,d", "set 3,e", "set 3,h", "set 3,l", "set 3,(hl)", "set 3,a", "set 4,b", "set 4,c", "set 4,d", "set 4,e", "set 4,h", "set 4,l", "set 4,(hl)", "set 4,a", "set 5,b", "set 5,c", "set 5,d", "set 5,e", "set 5,h", "set 5,l", "set 5,(hl)", "set 5,a", "set 6,b", "set 6,c", "set 6,d", "set 6,e", "set 6,h", "set 6,l", "set 6,(hl)", "set 6,a", "set 7,b", "set 7,c", "set 7,d", "set 7,e", "set 7,h", "set 7,l", "set 7,(hl)", "set 7,a"};
void loadSymbols()
{
used_symbols.clear();
for (int i=0; i<65536; ++i) symbols[i][0] = 0;
FILE *f = fopen("symbols.txt", "r");
if (!f) return;
while (true) {
uint16_t address;
char tmp[15];
const int result = fscanf(f, "%x %s", &address, tmp);
if (result != 2) break;
strcpy(symbols[address], tmp);
used_symbols.push_back(address);
}
fclose(f);
}
void saveSymbols()
{
FILE *f = fopen("symbols.txt", "w");
for (auto sym_addr : used_symbols)
{
fprintf(f, "0x%x %s\n", sym_addr, symbols[sym_addr]);
}
fclose(f);
}
const char *getBase(const uint16_t pos)
{
if (mem::readMem(pos) == 0xCB) {
opcode_size=2;
return bit_opcodes[mem::readMem(pos+1)];
} else {
opcode_size=1;
return base_opcodes[mem::readMem(pos)];
}
}
void printOpcode(const uint16_t pos)
{
char hex[4];
for (int i=0; i<4;++i)
{
if (opcode_size>i)
sprintf(hex, "%02x ", mem::readMem(pos+i));
else
sprintf(hex, " ");
strcat(buffer, hex);
}
}
const char *getAsm(const uint16_t pos)
{
opcode_size = 0;
char base[256];
strcpy(buffer, getBase(pos));
if (strstr(buffer, "4x"))
{
opcode_size+=2;
//const uint8_t memvalue = mem::readMem(pos);
//const uint16_t address = pos + 1;
const uint16_t word = mem::readMem(pos+1) + (mem::readMem(pos+2)<<8);
if (symbols[word][0]!=0) {
char *p = strstr(buffer, "$");
(*p)='%'; p++;
(*p)='s'; p++;
while (*(p-1) != 0) {
*p = *(p+3);
p++;
}
strcpy(base, buffer);
sprintf(buffer, base, symbols[word]);
} else {
strcpy(base, buffer);
sprintf(buffer, base, word);
}
}
if (strstr(buffer, "2x"))
{
opcode_size+=1;
strcpy(base, buffer);
sprintf(buffer, base, mem::readMem(pos+1));
}
if (strstr(buffer, "Xx"))
{
strcpy(base, buffer);
*strstr(base, "Xx") = '4';
opcode_size+=1;
sprintf(buffer, base, pos + opcode_size + (int8_t)mem::readMem(pos+1));
}
return buffer;
}
const char *getOpcode(const uint16_t pos)
{
opcode_size = 0;
buffer[0]=0;
const char *base = getBase(pos);
if (strstr(base, "4x")) opcode_size+=2;
if (strstr(base, "2x")) opcode_size+=1;
if (strstr(base, "Xx")) opcode_size+=1;
printOpcode(pos);
return buffer;
}
const int getOpcodeSize(const uint16_t pos)
{
opcode_size = 0;
const char *base = getBase(pos);
if (strstr(base, "4x")) opcode_size+=2;
if (strstr(base, "2x")) opcode_size+=1;
if (strstr(base, "Xx")) opcode_size+=1;
return opcode_size;
}
const char *getSymbol(const uint16_t pos)
{
return symbols[pos];
}
void setSymbol(const uint16_t pos, const char *sym)
{
if (sym) {
strcpy(symbols[pos], sym);
} else {
symbols[pos][0] = 0;
}
used_symbols.clear();
for (int i=0; i<65536; ++i) if (symbols[i][0]!=0) used_symbols.push_back(i);
saveSymbols();
}
const int getNumSymbols()
{
return used_symbols.size();
}
const uint16_t getSymbolAddress(const int pos)
{
return used_symbols[pos];
}
}

17
sm83dis.h Normal file
View File

@@ -0,0 +1,17 @@
#pragma once
#include <stdint.h>
namespace sm83dis
{
void loadSymbols();
void saveSymbols();
const char *getAsm(const uint16_t pos);
const char *getOpcode(const uint16_t pos);
const int getOpcodeSize(const uint16_t pos);
const char *getSymbol(const uint16_t pos);
void setSymbol(const uint16_t pos, const char *sym);
const int getNumSymbols();
const uint16_t getSymbolAddress(const int pos);
}

101
ui.cpp Normal file
View File

@@ -0,0 +1,101 @@
#include "ui.h"
#include <SDL2/SDL.h>
namespace ui
{
uint8_t colors[16][3] = {
{0,0,0},
{0,0,128},
{0,128,0},
{0,128,128},
{128,0,0},
{128,0,128},
{255,128,0},
{128,128,128},
{30,30,30},
{0,0,255},
{0,255,0},
{0,255,255},
{255,0,0},
{255,0,255},
{255,255,0},
{255,255,255},
};
SDL_Renderer *ren = nullptr;
SDL_Texture *tex = nullptr;
uint8_t offset_x = 0;
uint8_t offset_y = 0;
bool clicked = false;
SDL_Texture * createtexture(SDL_Renderer *renderer)
{
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, SDL_LoadBMP("font.bmp"));
SDL_SetTextureBlendMode(texture, SDL_BLENDMODE_BLEND);
return texture;
}
void setrenderer(SDL_Renderer *renderer, SDL_Texture *texture)
{
if (ren==renderer) return;
ren = renderer;
tex = texture;
offset_x = offset_y = 0;
}
void setoffset(uint8_t x, uint8_t y)
{
offset_x = x;
offset_y = y;
}
void box(int x, int y, int w, int h, uint8_t color)
{
SDL_Rect rect {((offset_x+x)*CHR_W)+3, ((offset_y+y)*CHR_H)+6, w*CHR_W-6, h*CHR_H-13};
SDL_SetRenderDrawColor(ren, colors[color][0], colors[color][1], colors[color][2], 255);
SDL_RenderDrawRect(ren, &rect);
}
void printrect(int x, int y, int w, int h, uint8_t color)
{
SDL_Rect rect {(offset_x+x)*CHR_W, (offset_y+y)*CHR_H, w*CHR_W, h*CHR_H};
SDL_SetRenderDrawColor(ren, colors[color][0], colors[color][1], colors[color][2], 255);
SDL_RenderFillRect(ren, &rect);
}
void printvoidrect(int x, int y, int w, int h, uint8_t color)
{
SDL_Rect rect {(offset_x+x)*CHR_W, (offset_y+y)*CHR_H, w*CHR_W, h*CHR_H};
SDL_SetRenderDrawColor(ren, colors[color][0], colors[color][1], colors[color][2], 255);
SDL_RenderDrawRect(ren, &rect);
}
void printchar(int x, int y, char chr, uint8_t color)
{
if (color != 255) SDL_SetRenderDrawColor(ren, colors[color][0], colors[color][1], colors[color][2], 255);
if (chr==32) return;
if (chr<32 || chr>127) chr = '.';
SDL_Rect src {((chr-32)&0xf)*CHR_W, ((chr-32)>>4)*CHR_H, CHR_W, CHR_H};
SDL_Rect dst {(offset_x+x)*CHR_W, (offset_y+y)*CHR_H, CHR_W, CHR_H};
SDL_RenderCopy(ren, tex, &src, &dst);
}
void printtxt(int x, int y, const char *text, uint8_t color)
{
SDL_SetTextureColorMod(tex, colors[color][0], colors[color][1], colors[color][2]);
for (int i=0; i<strlen(text);++i) if (text[i]!=32) printchar(x+i, y, text[i]);
}
void setClicked(const bool value)
{
clicked = value;
}
const bool getClicked()
{
return clicked;
}
}

38
ui.h Normal file
View File

@@ -0,0 +1,38 @@
#pragma once
#include <SDL2/SDL.h>
namespace ui
{
#define CHR_W 6
#define CHR_H 13
#define COLOR_BLACK 0
#define COLOR_DARK_BLUE 1
#define COLOR_GREEN 2
#define COLOR_TEAL 3
#define COLOR_BROWN 4
#define COLOR_PURPLE 5
#define COLOR_ORANGE 6
#define COLOR_GRAY 7
#define COLOR_DARK 8
#define COLOR_BLUE 9
#define COLOR_LIME 10
#define COLOR_CYAN 11
#define COLOR_RED 12
#define COLOR_MAGENTA 13
#define COLOR_YELLOW 14
#define COLOR_WHITE 15
SDL_Texture * createtexture(SDL_Renderer *renderer);
void setrenderer(SDL_Renderer *renderer, SDL_Texture *texture);
void setoffset(uint8_t x, uint8_t y);
void box(int x, int y, int w, int h, uint8_t color);
void printrect(int x, int y, int w, int h, uint8_t color);
void printvoidrect(int x, int y, int w, int h, uint8_t color);
void printchar(int x, int y, char chr, uint8_t color=255);
void printtxt(int x, int y, const char *text, uint8_t color);
void setClicked(const bool value);
const bool getClicked();
}

142
ui_menu.cpp Normal file
View File

@@ -0,0 +1,142 @@
#include "ui_menu.h"
#include "ui.h"
#include <vector>
#include <string>
namespace ui
{
namespace menu
{
#define OPTION_TYPE_NORMAL 0
#define OPTION_TYPE_SEPARATOR 1
#define OPTION_TYPE_BOOLEAN 2
struct option_t
{
std::string label;
int type;
int value;
int (*callback)(int);
};
struct menu_t
{
std::string label;
SDL_Rect rect;
std::vector<option_t> options;
};
void(*exit_callback)(void) = nullptr;
std::vector<menu_t> menus;
int visible_menu = -1;
int menu_x = 0;
void init()
{
// No se si hi ha algo que fer ací...
}
void show()
{
int mx, my;
Uint32 mb = SDL_GetMouseState(&mx, &my);
mx=mx/CHR_W; my=my/CHR_H;
int w;
ui::printrect(0, 0, 320, 1, COLOR_BLACK);
int opt_pos=1;
int index=0;
for (auto &menu : menus)
{
const int text_size = (menu.label.size()+2);
uint8_t text_color = COLOR_WHITE;
if (my<1 && mx>=opt_pos && mx<opt_pos+text_size)
{
ui::printrect(opt_pos-1, 0, text_size, 1, COLOR_DARK_BLUE);
text_color = COLOR_WHITE;
visible_menu = index;
menu_x = opt_pos-1;
}
ui::printtxt(opt_pos, 0, menu.label.c_str(), text_color);
opt_pos+=text_size;
index++;
}
if (visible_menu!=-1)
{
opt_pos=2;
menu_t &m = menus[visible_menu];
ui::printrect(menu_x, 1, 22, m.options.size()+2, COLOR_BLACK);
ui::box(menu_x, 1, 22, m.options.size()+2, COLOR_WHITE);
for (auto &option : m.options)
{
if (option.type!=OPTION_TYPE_SEPARATOR)
{
const int text_size = (option.label.size()+2);
uint8_t text_color = COLOR_WHITE;
if (my==opt_pos && mx>=menu_x && mx<menu_x+text_size)
{
ui::printrect(menu_x+1, opt_pos, 20, 1, COLOR_DARK_BLUE);
text_color = COLOR_WHITE;
if (ui::getClicked())
{
if (option.callback) option.value = option.callback(option.value);
if (exit_callback) exit_callback();
return;
}
}
ui::printtxt(menu_x+1, opt_pos, option.label.c_str(), text_color);
if (option.type==OPTION_TYPE_BOOLEAN)
{
const char *check = option.value?"[X]":"[ ]";
ui::printtxt(menu_x+18, opt_pos, check, text_color);
}
}
opt_pos++;
}
}
}
void setexitcallback(void(*callback)(void))
{
exit_callback = callback;
}
const int addsubmenu(const char *label)
{
menu_t m;
m.label = label;
m.rect = {0, 0, 100, 0};
menus.push_back(m);
return menus.size()-1;
}
void addoption(int menu, const char *label, int(*callback)(int))
{
option_t op;
op.type = OPTION_TYPE_NORMAL;
op.label = label;
op.callback = callback;
menus[menu].options.push_back(op);
menus[menu].rect.h += 15;
}
void addbooloption(int menu, const char *label, bool default_value, int(*callback)(int))
{
option_t op;
op.type = OPTION_TYPE_BOOLEAN;
op.label = label;
op.value = default_value?1:0;
op.callback = callback;
menus[menu].options.push_back(op);
menus[menu].rect.h += 15;
}
void addseparator(int menu)
{
option_t op;
op.type = OPTION_TYPE_SEPARATOR;
menus[menu].options.push_back(op);
}
}
}

15
ui_menu.h Normal file
View File

@@ -0,0 +1,15 @@
#pragma once
namespace ui
{
namespace menu
{
void init();
void show();
void setexitcallback(void(*callback)(void));
const int addsubmenu(const char *label);
void addoption(int menu, const char *label, int(*callback)(int));
void addbooloption(int menu, const char *label, bool default_value, int(*callback)(int));
void addseparator(int menu);
}
}

33
ui_window.cpp Normal file
View File

@@ -0,0 +1,33 @@
#include "ui_window.h"
#include <vector>
namespace ui
{
namespace window
{
struct window_t
{
Uint32 window;
bool (*callback)(SDL_Event*);
};
std::vector<window_t> windows;
void registerWindow(Uint32 window, bool(*callback)(SDL_Event*))
{
for (auto win : windows) if (win.window == window) return;
windows.push_back((window_t){window, callback});
}
void unregisterWindow(Uint32 window)
{
for (auto win = windows.begin(); win != windows.end(); win++) if ((*win).window == window) { windows.erase(win); return; }
}
bool sendEvent(Uint32 window, SDL_Event *e)
{
for (auto win : windows) if (win.window == window) return win.callback(e);
return true;
}
}
}

12
ui_window.h Normal file
View File

@@ -0,0 +1,12 @@
#pragma once
#include <SDL2/SDL.h>
namespace ui
{
namespace window
{
void registerWindow(Uint32 window, bool(*callback)(SDL_Event *e));
void unregisterWindow(Uint32 window);
bool sendEvent(Uint32 window, SDL_Event *e);
}
}