mirror of
https://github.com/ares-emulator/ares.git
synced 2026-11-10 01:11:44 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
926ffd9695 | ||
|
|
a1389a2ba3 | ||
|
|
5263ffb7aa | ||
|
|
1744bcb99c | ||
|
|
6362044c05 | ||
|
|
319b244af4 | ||
|
|
a3f1802845 | ||
|
|
4370acae2e | ||
|
|
5a804eac58 | ||
|
|
3b65b50aea | ||
|
|
a85ff8c437 | ||
|
|
a15d15047c | ||
|
|
f77aca7172 | ||
|
|
c32195cbd6 | ||
|
|
161366df9b | ||
|
|
4c43e85141 | ||
|
|
9da42c18c3 | ||
|
|
d115c7f6aa | ||
|
|
2efce0fd83 | ||
|
|
f6732133e7 |
No files matched your search
+2
-2
@@ -1,5 +1,5 @@
|
||||
bsnes (TM) Open Source Reference License
|
||||
Copyright (C) 2004 - 2007 byuu
|
||||
bsnes (TM) Reference License
|
||||
Copyright (C) 2004 - 2008 byuu
|
||||
All rights reserved
|
||||
|
||||
1. Definitions
|
||||
|
||||
+1
-7
@@ -1,5 +1,5 @@
|
||||
bsnes
|
||||
Version 0.026
|
||||
Version: 0.028
|
||||
Author: byuu
|
||||
|
||||
--------
|
||||
@@ -13,12 +13,6 @@ http://byuu.org/
|
||||
|
||||
Please see license.txt for important licensing information.
|
||||
|
||||
--------------
|
||||
Shortcut Keys:
|
||||
--------------
|
||||
Esc - Toggle menubar visibility
|
||||
F11 - Toggle fullscreen mode
|
||||
|
||||
------------------
|
||||
Known Limitations:
|
||||
------------------
|
||||
|
||||
+303
-321
@@ -1,321 +1,303 @@
|
||||
######################
|
||||
### bsnes makefile ###
|
||||
######################
|
||||
|
||||
ifeq ($(PLATFORM),)
|
||||
_null_: help
|
||||
endif
|
||||
|
||||
##################################
|
||||
### platform-specific settings ###
|
||||
##################################
|
||||
|
||||
ifeq ($(PLATFORM),x-gcc-lui)
|
||||
OS = unix
|
||||
CC = gcc
|
||||
CFLAGS = -O3 -fomit-frame-pointer -DPLATFORM_X -DCOMPILER_GCC -DPROCESSOR_X86 -DUI_LUI `pkg-config --cflags gtk+-2.0`
|
||||
AS = nasm
|
||||
ASFLAGS = -f elf
|
||||
LIBS = `pkg-config --libs gtk+-2.0` -lXv -lao
|
||||
LIBCO = libco_x86
|
||||
LIBUI = libui_gtk
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),x-gcc-lui-x64)
|
||||
OS = unix
|
||||
CC = gcc
|
||||
CFLAGS = -O3 -fomit-frame-pointer -DPLATFORM_X -DCOMPILER_GCC -DPROCESSOR_X86_64 -DUI_LUI `pkg-config --cflags gtk+-2.0`
|
||||
AS = yasm
|
||||
ASFLAGS = -f elf64
|
||||
LIBS = `pkg-config --libs gtk+-2.0` -lXv -lao
|
||||
LIBCO = libco_x86_64
|
||||
LIBUI = libui_gtk
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),win-visualc-lui)
|
||||
OS = win
|
||||
CC = cl
|
||||
CFLAGS = /nologo /wd4996 /O2 /EHsc /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_LUI
|
||||
AS = nasm
|
||||
ASFLAGS = -f win32 -DWIN32
|
||||
LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib kernel32.lib user32.lib gdi32.lib shell32.lib winmm.lib comdlg32.lib comctl32.lib
|
||||
LIBCO = libco_x86
|
||||
LIBUI = libui_win
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),win-visualc-lui-pgi)
|
||||
OS = win
|
||||
CC = cl
|
||||
CFLAGS = /nologo /wd4996 /O2 /GL /EHsc /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_LUI
|
||||
AS = nasm
|
||||
ASFLAGS = -f win32 -DWIN32
|
||||
LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib kernel32.lib user32.lib gdi32.lib shell32.lib winmm.lib comdlg32.lib comctl32.lib
|
||||
LINK = /link /PGD:bsnes.pgd /LTCG:PGINSTRUMENT
|
||||
LIBCO = libco_x86
|
||||
LIBUI = libui_win
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),win-visualc-lui-pgo)
|
||||
OS = win
|
||||
CC = cl
|
||||
CFLAGS = /nologo /wd4996 /O2 /GL /EHsc /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_LUI
|
||||
AS = nasm
|
||||
ASFLAGS = -f win32 -DWIN32
|
||||
LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib kernel32.lib user32.lib gdi32.lib shell32.lib winmm.lib comdlg32.lib comctl32.lib
|
||||
LINK = /link /PGD:bsnes.pgd /LTCG:PGOPTIMIZE
|
||||
LIBCO = libco_x86
|
||||
LIBUI = libui_win
|
||||
endif
|
||||
|
||||
ifeq ($(PLATFORM),win-mingw-lui)
|
||||
OS = win
|
||||
CC = mingw32-gcc
|
||||
CFLAGS = -mwindows -O3 -fomit-frame-pointer -DPLATFORM_WIN -DCOMPILER_GCC -DPROCESSOR_X86 -DUI_LUI
|
||||
AS = nasm
|
||||
ASFLAGS = -f win32 -DWIN32
|
||||
LIBS = -ld3d9 -lddraw -ldsound -ldinput8 -ldxguid -luuid -lkernel32 -luser32 -lgdi32 -lshell32 -lwinmm -lcomdlg32 -lcomctl32
|
||||
LIBCO = libco_x86
|
||||
LIBUI = libui_win
|
||||
endif
|
||||
|
||||
#####################################
|
||||
### compiler / assembler switches ###
|
||||
#####################################
|
||||
|
||||
ifeq ($(CC),gcc)
|
||||
OUT = -obsnes
|
||||
CPP = g++
|
||||
OBJ = o
|
||||
CARGS = -c $< -o $@
|
||||
DEFINE = -D
|
||||
endif
|
||||
|
||||
ifeq ($(CC),mingw32-gcc)
|
||||
OUT = -obsnes
|
||||
CPP = mingw32-g++
|
||||
OBJ = o
|
||||
CARGS = -c $< -o $@
|
||||
DEFINE = -D
|
||||
endif
|
||||
|
||||
ifeq ($(CC),cl)
|
||||
OUT = /Febsnes
|
||||
CPP = cl
|
||||
OBJ = obj
|
||||
CARGS = /c $< /Fo$@
|
||||
DEFINE = /D
|
||||
endif
|
||||
|
||||
ifeq ($(AS),nasm)
|
||||
ASARGS = $< -o $@
|
||||
endif
|
||||
|
||||
ifeq ($(AS),yasm)
|
||||
ASARGS = $< -o $@
|
||||
endif
|
||||
|
||||
###################
|
||||
### OS switches ###
|
||||
###################
|
||||
|
||||
ifeq ($(OS),unix)
|
||||
RM = rm -f
|
||||
endif
|
||||
|
||||
ifeq ($(OS),win)
|
||||
OUT := $(OUT).exe
|
||||
RM = del
|
||||
endif
|
||||
|
||||
####################################
|
||||
### main target and dependencies ###
|
||||
####################################
|
||||
|
||||
OBJECTS = main.$(OBJ) $(LIBCO).$(OBJ) $(LIBUI).$(OBJ) \
|
||||
libstring.$(OBJ) \
|
||||
reader.$(OBJ) cart.$(OBJ) cheat.$(OBJ) memory.$(OBJ) smemory.$(OBJ) \
|
||||
cpu.$(OBJ) scpu.$(OBJ) smp.$(OBJ) ssmp.$(OBJ) bdsp.$(OBJ) ppu.$(OBJ) \
|
||||
bppu.$(OBJ) snes.$(OBJ) bsx.$(OBJ) superfx.$(OBJ) srtc.$(OBJ) \
|
||||
sdd1.$(OBJ) cx4.$(OBJ) dsp1.$(OBJ) dsp2.$(OBJ) dsp3.$(OBJ) dsp4.$(OBJ) \
|
||||
obc1.$(OBJ) st010.$(OBJ)
|
||||
|
||||
ifeq ($(GZIP_SUPPORT),true)
|
||||
OBJECTS += adler32.$(OBJ) compress.$(OBJ) crc32.$(OBJ) deflate.$(OBJ) \
|
||||
gzio.$(OBJ) inffast.$(OBJ) inflate.$(OBJ) inftrees.$(OBJ) ioapi.$(OBJ) \
|
||||
trees.$(OBJ) unzip.$(OBJ) zip.$(OBJ) zutil.$(OBJ)
|
||||
CFLAGS += $(DEFINE)GZIP_SUPPORT
|
||||
endif
|
||||
|
||||
ifeq ($(JMA_SUPPORT),true)
|
||||
OBJECTS += jma.$(OBJ) jcrc32.$(OBJ) lzmadec.$(OBJ) 7zlzma.$(OBJ) \
|
||||
iiostrm.$(OBJ) inbyte.$(OBJ) lzma.$(OBJ) winout.$(OBJ)
|
||||
CFLAGS += $(DEFINE)JMA_SUPPORT
|
||||
endif
|
||||
|
||||
ifeq ($(OS),win)
|
||||
ifeq ($(CC),cl)
|
||||
OBJECTS += bsnes.res
|
||||
endif
|
||||
ifeq ($(CC),mingw32-gcc)
|
||||
OBJECTS += bsnesrc.o
|
||||
endif
|
||||
endif
|
||||
|
||||
all: $(OBJECTS)
|
||||
$(CPP) $(OUT) $(CFLAGS) $(OBJECTS) $(LIBS) $(LINK)
|
||||
|
||||
install:
|
||||
cp bsnes /usr/local/bin/bsnes
|
||||
cp data/bsnes.png /usr/local/share/icons/bsnes.png
|
||||
chmod 775 /usr/local/bin/bsnes /usr/local/share/icons/bsnes.png
|
||||
|
||||
######################
|
||||
### implicit rules ###
|
||||
######################
|
||||
|
||||
%.$(OBJ): $<
|
||||
$(if $(filter %.asm,$<),$(AS) $(ASFLAGS) $(ASARGS))
|
||||
$(if $(filter %.c,$<),$(CC) $(CFLAGS) $(CARGS))
|
||||
$(if $(filter %.cpp,$<),$(CPP) $(CFLAGS) $(CARGS))
|
||||
|
||||
#########################
|
||||
### platform-specific ###
|
||||
#########################
|
||||
main.$(OBJ): ui/main.cpp config/* ui/* ui/video/* ui/audio/* ui/input/* \
|
||||
ui/lui/* ui/lui/loader/* ui/lui/settings/* \
|
||||
ui/win/* ui/win/settings/* ui/win/debugger/*
|
||||
|
||||
bsnes.res: ui/bsnes.rc ; rc /r /fobsnes.res ui/bsnes.rc
|
||||
bsnesrc.o: ui/bsnes.rc ; windres -I data ui/bsnes.rc bsnesrc.o
|
||||
|
||||
#############
|
||||
### libco ###
|
||||
#############
|
||||
libco_x86.$(OBJ) : lib/libco_x86.asm lib/*
|
||||
libco_x86_64.$(OBJ): lib/libco_x86_64.asm lib/*
|
||||
|
||||
#############
|
||||
### libui ###
|
||||
#############
|
||||
libui_gtk.$(OBJ): lib/libui_gtk.cpp lib/*
|
||||
libui_win.$(OBJ): lib/libui_win.cpp lib/*
|
||||
|
||||
#################
|
||||
### libraries ###
|
||||
#################
|
||||
libstring.$(OBJ): lib/libstring.cpp lib/*
|
||||
|
||||
#################
|
||||
### utilities ###
|
||||
#################
|
||||
reader.$(OBJ): reader/reader.cpp reader/*
|
||||
cart.$(OBJ) : cart/cart.cpp cart/*
|
||||
cheat.$(OBJ) : cheat/cheat.cpp cheat/*
|
||||
|
||||
##############
|
||||
### memory ###
|
||||
##############
|
||||
memory.$(OBJ) : memory/memory.cpp memory/*
|
||||
bmemory.$(OBJ): memory/bmemory/bmemory.cpp memory/bmemory/* memory/bmemory/mapper/*
|
||||
smemory.$(OBJ): memory/smemory/smemory.cpp memory/smemory/* memory/smemory/mapper/*
|
||||
|
||||
###########
|
||||
### cpu ###
|
||||
###########
|
||||
cpu.$(OBJ) : cpu/cpu.cpp cpu/*
|
||||
scpu.$(OBJ): cpu/scpu/scpu.cpp cpu/scpu/* cpu/scpu/core/* cpu/scpu/dma/* cpu/scpu/memory/* cpu/scpu/mmio/* cpu/scpu/timing/*
|
||||
|
||||
###########
|
||||
### smp ###
|
||||
###########
|
||||
smp.$(OBJ) : smp/smp.cpp smp/*
|
||||
ssmp.$(OBJ): smp/ssmp/ssmp.cpp smp/ssmp/* smp/ssmp/core/* smp/ssmp/memory/* smp/ssmp/timing/*
|
||||
|
||||
###########
|
||||
### dsp ###
|
||||
###########
|
||||
adsp.$(OBJ): dsp/adsp/adsp.cpp dsp/adsp/*
|
||||
bdsp.$(OBJ): dsp/bdsp/bdsp.cpp dsp/bdsp/*
|
||||
|
||||
###########
|
||||
### ppu ###
|
||||
###########
|
||||
ppu.$(OBJ) : ppu/ppu.cpp ppu/*
|
||||
bppu.$(OBJ): ppu/bppu/bppu.cpp ppu/bppu/*
|
||||
|
||||
############
|
||||
### snes ###
|
||||
############
|
||||
snes.$(OBJ): snes/snes.cpp snes/* snes/scheduler/* snes/video/* snes/audio/* snes/input/*
|
||||
|
||||
#####################
|
||||
### special chips ###
|
||||
#####################
|
||||
bsx.$(OBJ) : chip/bsx/bsx.cpp chip/bsx/*
|
||||
superfx.$(OBJ): chip/superfx/superfx.cpp chip/superfx/* chip/superfx/core/* chip/superfx/memory/*
|
||||
srtc.$(OBJ) : chip/srtc/srtc.cpp chip/srtc/*
|
||||
sdd1.$(OBJ) : chip/sdd1/sdd1.cpp chip/sdd1/*
|
||||
cx4.$(OBJ) : chip/cx4/cx4.cpp chip/cx4/*
|
||||
dsp1.$(OBJ) : chip/dsp1/dsp1.cpp chip/dsp1/*
|
||||
dsp2.$(OBJ) : chip/dsp2/dsp2.cpp chip/dsp2/*
|
||||
dsp3.$(OBJ) : chip/dsp3/dsp3.cpp chip/dsp3/*
|
||||
dsp4.$(OBJ) : chip/dsp4/dsp4.cpp chip/dsp4/*
|
||||
obc1.$(OBJ) : chip/obc1/obc1.cpp chip/obc1/*
|
||||
st010.$(OBJ) : chip/st010/st010.cpp chip/st010/*
|
||||
|
||||
############
|
||||
### zlib ###
|
||||
############
|
||||
adler32.$(OBJ) : reader/zlib/adler32.c reader/zlib/*
|
||||
compress.$(OBJ): reader/zlib/compress.c reader/zlib/*
|
||||
crc32.$(OBJ) : reader/zlib/crc32.c reader/zlib/*
|
||||
deflate.$(OBJ) : reader/zlib/deflate.c reader/zlib/*
|
||||
gzio.$(OBJ) : reader/zlib/gzio.c reader/zlib/*
|
||||
inffast.$(OBJ) : reader/zlib/inffast.c reader/zlib/*
|
||||
inflate.$(OBJ) : reader/zlib/inflate.c reader/zlib/*
|
||||
inftrees.$(OBJ): reader/zlib/inftrees.c reader/zlib/*
|
||||
ioapi.$(OBJ) : reader/zlib/ioapi.c reader/zlib/*
|
||||
trees.$(OBJ) : reader/zlib/trees.c reader/zlib/*
|
||||
unzip.$(OBJ) : reader/zlib/unzip.c reader/zlib/*
|
||||
zip.$(OBJ) : reader/zlib/zip.c reader/zlib/*
|
||||
zutil.$(OBJ) : reader/zlib/zutil.c reader/zlib/*
|
||||
|
||||
###########
|
||||
### jma ###
|
||||
###########
|
||||
jma.$(OBJ) : reader/jma/jma.cpp reader/jma/*
|
||||
jcrc32.$(OBJ) : reader/jma/jcrc32.cpp reader/jma/*
|
||||
lzmadec.$(OBJ): reader/jma/lzmadec.cpp reader/jma/*
|
||||
7zlzma.$(OBJ) : reader/jma/7zlzma.cpp reader/jma/*
|
||||
iiostrm.$(OBJ): reader/jma/iiostrm.cpp reader/jma/*
|
||||
inbyte.$(OBJ) : reader/jma/inbyte.cpp reader/jma/*
|
||||
lzma.$(OBJ) : reader/jma/lzma.cpp reader/jma/*
|
||||
winout.$(OBJ) : reader/jma/winout.cpp reader/jma/*
|
||||
|
||||
####################
|
||||
### misc targets ###
|
||||
####################
|
||||
clean:
|
||||
-@$(RM) *.$(OBJ)
|
||||
-@$(RM) *.res
|
||||
-@$(RM) *.pgd
|
||||
-@$(RM) *.pgc
|
||||
-@$(RM) *.ilk
|
||||
-@$(RM) *.pdb
|
||||
-@$(RM) *.manifest
|
||||
|
||||
help:
|
||||
@echo "Usage: $(MAKE) PLATFORM=platform [options]"
|
||||
@echo ""
|
||||
@echo "Available platform targets:"
|
||||
@echo " x-gcc-lui - Linux / BSD (i386) (requires nasm)"
|
||||
@echo " x-gcc-lui-x64 - Linux / BSD (amd64) (requires yasm)"
|
||||
@echo " win-mingw-lui - Windows (i386) (requires nasm)"
|
||||
@echo " win-visualc-lui - Windows (i386) (requires nasm)"
|
||||
@echo ""
|
||||
@echo "Available options:"
|
||||
@echo " GZIP_SUPPORT=[true|false] - Enable ZIP / GZ support (default=false)"
|
||||
@echo " JMA_SUPPORT=[true|false] - Enable JMA support (default=false)"
|
||||
@echo ""
|
||||
@echo "Example: $(MAKE) PLATFORM=x-gcc-lui GZIP_SUPPORT=true"
|
||||
@echo ""
|
||||
include lib/nall/Makefile.string
|
||||
|
||||
prefix = /usr/local
|
||||
arch = ARCH_LSB
|
||||
|
||||
################
|
||||
### compiler ###
|
||||
################
|
||||
|
||||
ifneq ($(findstring gcc,$(compiler)),) # GCC family
|
||||
flags = -O3 -fomit-frame-pointer -Ilib
|
||||
c = $(compiler) $(flags)
|
||||
cpp = $(subst cc,++,$(compiler)) $(flags)
|
||||
obj = o
|
||||
rule = -c $< -o $@
|
||||
link =
|
||||
mkbin = -o$1
|
||||
mkdef = -D$1
|
||||
mklib = -l$1
|
||||
else ifeq ($(compiler),cl) # Visual C++
|
||||
flags = /nologo /wd4355 /wd4996 /O2 /EHsc /Ilib
|
||||
c = cl $(flags)
|
||||
cpp = cl $(flags)
|
||||
obj = obj
|
||||
rule = /c $< /Fo$@
|
||||
link = /link
|
||||
mkbin = /Fe$1
|
||||
mkdef = /D$1
|
||||
mklib = $1.lib
|
||||
else
|
||||
unknown_compiler: help;
|
||||
endif
|
||||
|
||||
##########
|
||||
### os ###
|
||||
##########
|
||||
|
||||
ifeq ($(platform),x) # X11
|
||||
ruby = video.glx video.xv video.sdl audio.openal audio.oss audio.ao input.sdl input.x
|
||||
arch += PLATFORM_X
|
||||
link += `pkg-config --libs gtk+-2.0`
|
||||
delete = rm -f $1
|
||||
else ifeq ($(platform),win) # Windows
|
||||
ruby = video.direct3d video.directdraw video.gdi audio.directsound input.directinput
|
||||
arch += PLATFORM_WIN
|
||||
link += $(if $(findstring mingw,$(compiler)),-mwindows)
|
||||
link += $(call mklib,uuid)
|
||||
link += $(call mklib,kernel32)
|
||||
link += $(call mklib,user32)
|
||||
link += $(call mklib,gdi32)
|
||||
link += $(call mklib,shell32)
|
||||
link += $(call mklib,winmm)
|
||||
link += $(call mklib,comdlg32)
|
||||
link += $(call mklib,comctl32)
|
||||
delete = $(if $(findstring i586-mingw-gcc,$(compiler)),rm -f $1,del $(subst /,\,$1))
|
||||
else
|
||||
unknown_platform: help;
|
||||
endif
|
||||
|
||||
############
|
||||
### ruby ###
|
||||
############
|
||||
|
||||
link += $(if $(findstring video.direct3d,$(ruby)),$(call mklib,d3d9))
|
||||
link += $(if $(findstring video.directdraw,$(ruby)),$(call mklib,ddraw))
|
||||
link += $(if $(findstring video.glx,$(ruby)),$(call mklib,GL))
|
||||
link += $(if $(findstring video.xv,$(ruby)),$(call mklib,Xv))
|
||||
link += $(if $(findstring audio.ao,$(ruby)),$(call mklib,ao))
|
||||
link += $(if $(findstring audio.directsound,$(ruby)),$(call mklib,dsound))
|
||||
link += $(if $(findstring audio.openal,$(ruby)),$(call mklib,openal) $(call mklib,alut))
|
||||
link += $(if $(findstring input.directinput,$(ruby)),$(call mklib,dinput8) $(call mklib,dxguid))
|
||||
link += $(if $(findstring input.sdl,$(ruby)),`sdl-config --libs`)
|
||||
|
||||
####################################
|
||||
### main target and dependencies ###
|
||||
####################################
|
||||
|
||||
objects = main libco hiro ruby $(ruby) string reader cart cheat \
|
||||
memory smemory cpu scpu smp ssmp bdsp ppu bppu snes \
|
||||
bsx srtc sdd1 cx4 dsp1 dsp2 dsp3 dsp4 obc1 st010
|
||||
|
||||
ifeq ($(enable_gzip),true)
|
||||
objects += adler32 compress crc32 deflate gzio inffast inflate inftrees ioapi trees unzip zip zutil
|
||||
flags += $(call mkdef,GZIP_SUPPORT)
|
||||
endif
|
||||
|
||||
ifeq ($(enable_jma),true)
|
||||
objects += jma jcrc32 lzmadec 7zlzma iiostrm inbyte lzma winout
|
||||
flags += $(call mkdef,JMA_SUPPORT)
|
||||
endif
|
||||
|
||||
arch := $(patsubst %,$(call mkdef,%),$(arch))
|
||||
objects := $(patsubst %,obj/%.$(obj),$(objects))
|
||||
rubydef := $(foreach c,$(subst .,_,$(call strupper,$(ruby))),$(call mkdef,$c))
|
||||
|
||||
# Windows resource file
|
||||
ifeq ($(platform),win)
|
||||
ifeq ($(compiler),cl)
|
||||
objects += obj/bsnes.res
|
||||
else ifneq ($(findstring gcc,$(compiler)),)
|
||||
objects += obj/bsnesrc.$(obj)
|
||||
endif
|
||||
endif
|
||||
|
||||
################
|
||||
### implicit ###
|
||||
################
|
||||
|
||||
compile = \
|
||||
$(strip \
|
||||
$(if $(filter %.c,$<), \
|
||||
$(c) $1 $(rule), \
|
||||
$(if $(filter %.cpp,$<), \
|
||||
$(cpp) $1 $(rule) \
|
||||
) \
|
||||
) \
|
||||
)
|
||||
|
||||
%.$(obj): $<; $(call compile)
|
||||
|
||||
all: build;
|
||||
|
||||
############
|
||||
### main ###
|
||||
############
|
||||
|
||||
obj/main.$(obj): ui/main.cpp config/* lib/nall/* lib/ruby/* ui/* ui/loader/* ui/settings/*
|
||||
$(call compile,$(arch))
|
||||
|
||||
obj/bsnes.res : ui/bsnes.rc; rc /r /foobj/bsnes.res ui/bsnes.rc
|
||||
obj/bsnesrc.$(obj): ui/bsnes.rc; windres -I data ui/bsnes.rc obj/bsnesrc.$(obj)
|
||||
|
||||
############
|
||||
### ruby ###
|
||||
############
|
||||
|
||||
obj/ruby.$(obj) : lib/ruby/ruby.cpp lib/ruby/*
|
||||
$(call compile,$(rubydef))
|
||||
obj/video.direct3d.$(obj) : lib/ruby/video/direct3d.cpp lib/ruby/video/direct3d.*
|
||||
obj/video.directdraw.$(obj) : lib/ruby/video/directdraw.cpp lib/ruby/video/directdraw.*
|
||||
obj/video.gdi.$(obj) : lib/ruby/video/gdi.cpp lib/ruby/video/gdi.*
|
||||
obj/video.glx.$(obj) : lib/ruby/video/glx.cpp lib/ruby/video/glx.*
|
||||
obj/video.sdl.$(obj) : lib/ruby/video/sdl.cpp lib/ruby/video/sdl.*
|
||||
$(call compile,`sdl-config --cflags`)
|
||||
obj/video.xv.$(obj) : lib/ruby/video/xv.cpp lib/ruby/video/xv.*
|
||||
obj/audio.ao.$(obj) : lib/ruby/audio/ao.cpp lib/ruby/audio/ao.*
|
||||
obj/audio.directsound.$(obj): lib/ruby/audio/directsound.cpp lib/ruby/audio/directsound.*
|
||||
obj/audio.openal.$(obj) : lib/ruby/audio/openal.cpp lib/ruby/audio/openal.*
|
||||
obj/audio.oss.$(obj) : lib/ruby/audio/oss.cpp lib/ruby/audio/oss.*
|
||||
obj/input.directinput.$(obj): lib/ruby/input/directinput.cpp lib/ruby/input/directinput.*
|
||||
obj/input.sdl.$(obj) : lib/ruby/input/sdl.cpp lib/ruby/input/sdl.*
|
||||
$(call compile,`sdl-config --cflags`)
|
||||
obj/input.x.$(obj) : lib/ruby/input/x.cpp lib/ruby/input/x.*
|
||||
|
||||
############
|
||||
### hiro ###
|
||||
############
|
||||
|
||||
obj/hiro.$(obj): lib/hiro.cpp lib/hiro.* lib/hiro_gtk/* lib/hiro_win/*
|
||||
$(call compile,$(if $(call streq,$(platform),x),`pkg-config --cflags gtk+-2.0`))
|
||||
|
||||
#################
|
||||
### libraries ###
|
||||
#################
|
||||
|
||||
obj/libco.$(obj): lib/libco.c lib/libco.* lib/libco/*
|
||||
obj/string.$(obj): lib/nall/string.cpp lib/nall/*
|
||||
|
||||
#################
|
||||
### utilities ###
|
||||
#################
|
||||
|
||||
obj/reader.$(obj): reader/reader.cpp reader/*
|
||||
obj/cart.$(obj) : cart/cart.cpp cart/*
|
||||
obj/cheat.$(obj) : cheat/cheat.cpp cheat/*
|
||||
|
||||
##############
|
||||
### memory ###
|
||||
##############
|
||||
|
||||
obj/memory.$(obj) : memory/memory.cpp memory/*
|
||||
obj/bmemory.$(obj): memory/bmemory/bmemory.cpp memory/bmemory/* memory/bmemory/mapper/*
|
||||
obj/smemory.$(obj): memory/smemory/smemory.cpp memory/smemory/* memory/smemory/mapper/*
|
||||
|
||||
###########
|
||||
### cpu ###
|
||||
###########
|
||||
|
||||
obj/cpu.$(obj) : cpu/cpu.cpp cpu/*
|
||||
obj/scpu.$(obj): cpu/scpu/scpu.cpp cpu/scpu/* cpu/scpu/core/* cpu/scpu/dma/* cpu/scpu/memory/* cpu/scpu/mmio/* cpu/scpu/timing/*
|
||||
|
||||
###########
|
||||
### smp ###
|
||||
###########
|
||||
|
||||
obj/smp.$(obj) : smp/smp.cpp smp/*
|
||||
obj/ssmp.$(obj): smp/ssmp/ssmp.cpp smp/ssmp/* smp/ssmp/core/* smp/ssmp/memory/* smp/ssmp/timing/*
|
||||
|
||||
###########
|
||||
### dsp ###
|
||||
###########
|
||||
|
||||
obj/adsp.$(obj): dsp/adsp/adsp.cpp dsp/adsp/*
|
||||
obj/bdsp.$(obj): dsp/bdsp/bdsp.cpp dsp/bdsp/*
|
||||
|
||||
###########
|
||||
### ppu ###
|
||||
###########
|
||||
|
||||
obj/ppu.$(obj) : ppu/ppu.cpp ppu/*
|
||||
obj/bppu.$(obj): ppu/bppu/bppu.cpp ppu/bppu/*
|
||||
|
||||
############
|
||||
### snes ###
|
||||
############
|
||||
|
||||
obj/snes.$(obj): snes/snes.cpp snes/* snes/scheduler/* snes/video/* snes/audio/* snes/input/*
|
||||
|
||||
#####################
|
||||
### special chips ###
|
||||
#####################
|
||||
|
||||
obj/bsx.$(obj) : chip/bsx/bsx.cpp chip/bsx/*
|
||||
obj/srtc.$(obj) : chip/srtc/srtc.cpp chip/srtc/*
|
||||
obj/sdd1.$(obj) : chip/sdd1/sdd1.cpp chip/sdd1/*
|
||||
obj/cx4.$(obj) : chip/cx4/cx4.cpp chip/cx4/*
|
||||
obj/dsp1.$(obj) : chip/dsp1/dsp1.cpp chip/dsp1/*
|
||||
obj/dsp2.$(obj) : chip/dsp2/dsp2.cpp chip/dsp2/*
|
||||
obj/dsp3.$(obj) : chip/dsp3/dsp3.cpp chip/dsp3/*
|
||||
obj/dsp4.$(obj) : chip/dsp4/dsp4.cpp chip/dsp4/*
|
||||
obj/obc1.$(obj) : chip/obc1/obc1.cpp chip/obc1/*
|
||||
obj/st010.$(obj): chip/st010/st010.cpp chip/st010/*
|
||||
|
||||
############
|
||||
### zlib ###
|
||||
############
|
||||
|
||||
obj/adler32.$(obj) : reader/zlib/adler32.c reader/zlib/*
|
||||
obj/compress.$(obj): reader/zlib/compress.c reader/zlib/*
|
||||
obj/crc32.$(obj) : reader/zlib/crc32.c reader/zlib/*
|
||||
obj/deflate.$(obj) : reader/zlib/deflate.c reader/zlib/*
|
||||
obj/gzio.$(obj) : reader/zlib/gzio.c reader/zlib/*
|
||||
obj/inffast.$(obj) : reader/zlib/inffast.c reader/zlib/*
|
||||
obj/inflate.$(obj) : reader/zlib/inflate.c reader/zlib/*
|
||||
obj/inftrees.$(obj): reader/zlib/inftrees.c reader/zlib/*
|
||||
obj/ioapi.$(obj) : reader/zlib/ioapi.c reader/zlib/*
|
||||
obj/trees.$(obj) : reader/zlib/trees.c reader/zlib/*
|
||||
obj/unzip.$(obj) : reader/zlib/unzip.c reader/zlib/*
|
||||
obj/zip.$(obj) : reader/zlib/zip.c reader/zlib/*
|
||||
obj/zutil.$(obj) : reader/zlib/zutil.c reader/zlib/*
|
||||
|
||||
###########
|
||||
### jma ###
|
||||
###########
|
||||
|
||||
obj/jma.$(obj) : reader/jma/jma.cpp reader/jma/*
|
||||
obj/jcrc32.$(obj) : reader/jma/jcrc32.cpp reader/jma/*
|
||||
obj/lzmadec.$(obj): reader/jma/lzmadec.cpp reader/jma/*
|
||||
obj/7zlzma.$(obj) : reader/jma/7zlzma.cpp reader/jma/*
|
||||
obj/iiostrm.$(obj): reader/jma/iiostrm.cpp reader/jma/*
|
||||
obj/inbyte.$(obj) : reader/jma/inbyte.cpp reader/jma/*
|
||||
obj/lzma.$(obj) : reader/jma/lzma.cpp reader/jma/*
|
||||
obj/winout.$(obj) : reader/jma/winout.cpp reader/jma/*
|
||||
|
||||
###############
|
||||
### targets ###
|
||||
###############
|
||||
|
||||
build: $(objects)
|
||||
$(strip $(cpp) $(call mkbin,../bsnes) $(objects) $(link))
|
||||
|
||||
install:
|
||||
install -m 755 ../bsnes $(prefix)/bin/bsnes
|
||||
install -m 644 data/bsnes.png $(prefix)/share/icons/bsnes.png
|
||||
|
||||
clean:
|
||||
-@$(call delete,obj/*.$(obj))
|
||||
-@$(call delete,*.res)
|
||||
-@$(call delete,*.pgd)
|
||||
-@$(call delete,*.pgc)
|
||||
-@$(call delete,*.ilk)
|
||||
-@$(call delete,*.pdb)
|
||||
-@$(call delete,*.manifest)
|
||||
|
||||
help:
|
||||
@echo "Usage: $(MAKE) platform=(os) compiler=(cc) [options]"
|
||||
@echo ""
|
||||
@echo "Supported platforms:"
|
||||
@echo " x - Linux / BSD (x86, x86-64)"
|
||||
@echo " win - Windows (x86, x86-64)"
|
||||
@echo ""
|
||||
@echo "Supported compilers:"
|
||||
@echo " gcc - GCC compiler"
|
||||
@echo " mingw32-gcc - MinGW compiler"
|
||||
@echo " i586-mingw32-gcc - MinGW cross compiler"
|
||||
@echo " cl - Visual C++"
|
||||
@echo ""
|
||||
@echo "Available options:"
|
||||
@echo " enable_gzip=[true|false] - Enable ZIP / GZ support (default=false)"
|
||||
@echo " enable_jma=[true|false] - Enable JMA support (default=false)"
|
||||
@echo ""
|
||||
@echo "Example: $(MAKE) platform=x compiler=gcc enable_gzip=true"
|
||||
@echo ""
|
||||
+55
-53
@@ -1,53 +1,55 @@
|
||||
#define BSNES_VERSION "0.026"
|
||||
#define BSNES_TITLE "bsnes v" BSNES_VERSION
|
||||
|
||||
#define BUSCORE sBus
|
||||
#define CPUCORE sCPU
|
||||
#define SMPCORE sSMP
|
||||
#define DSPCORE bDSP
|
||||
#define PPUCORE bPPU
|
||||
|
||||
//#define FAVOR_ACCURACY
|
||||
#define FAVOR_SPEED
|
||||
|
||||
//game genie + pro action replay code support (~1-3% speed hit)
|
||||
#define CHEAT_SYSTEM
|
||||
|
||||
#if defined(PROCESSOR_X86)
|
||||
#define ARCH_LSB
|
||||
#include "lib/libco_x86.h"
|
||||
#elif defined(PROCESSOR_X86_64)
|
||||
#define ARCH_LSB
|
||||
#include "lib/libco_x86_64.h"
|
||||
#elif defined(PROCESSOR_G5)
|
||||
#define ARCH_MSB
|
||||
#else
|
||||
#error "unsupported processor"
|
||||
#endif
|
||||
|
||||
#include "lib/libbase.h"
|
||||
#include "lib/libfunction.h"
|
||||
#include "lib/libarray.h"
|
||||
#include "lib/libvector.h"
|
||||
#include "lib/libstring.h"
|
||||
#include "lib/libconfig.h"
|
||||
|
||||
//platform-specific global functions
|
||||
void alert(const char*, ...);
|
||||
void dprintf(const char*, ...);
|
||||
void dprintf(uint, const char*, ...);
|
||||
|
||||
namespace source {
|
||||
enum {
|
||||
none = 0,
|
||||
debug,
|
||||
cpu,
|
||||
ppu,
|
||||
smp,
|
||||
dsp,
|
||||
bus,
|
||||
};
|
||||
};
|
||||
|
||||
//various class interfaces
|
||||
#include "interface.h"
|
||||
#define BSNES_VERSION "0.028"
|
||||
#define BSNES_TITLE "bsnes v" BSNES_VERSION
|
||||
|
||||
#define BUSCORE sBus
|
||||
#define CPUCORE sCPU
|
||||
#define SMPCORE sSMP
|
||||
#define DSPCORE bDSP
|
||||
#define PPUCORE bPPU
|
||||
|
||||
//FAVOR_ACCURACY calculates RTO during frameskip, whereas FAVOR_SPEED does not
|
||||
//frameskip offers near-zero speedup if RTO is calculated
|
||||
//accuracy is not affected by this define when frameskipping is off
|
||||
|
||||
//#define FAVOR_ACCURACY
|
||||
#define FAVOR_SPEED
|
||||
|
||||
//game genie + pro action replay code support (~1-3% speed hit)
|
||||
#define CHEAT_SYSTEM
|
||||
|
||||
#if !defined(ARCH_LSB) && !defined(ARCH_MSB)
|
||||
#define ARCH_LSB //guess
|
||||
#endif
|
||||
|
||||
#include <nall/algorithm.hpp>
|
||||
#include <nall/array.hpp>
|
||||
#include <nall/bit.hpp>
|
||||
#include <nall/config.hpp>
|
||||
#include <nall/function.hpp>
|
||||
#include <nall/new.hpp>
|
||||
#include <nall/sort.hpp>
|
||||
#include <nall/string.hpp>
|
||||
#include <nall/vector.hpp>
|
||||
using namespace nall;
|
||||
|
||||
#include <libco.h>
|
||||
#include <bbase.h>
|
||||
|
||||
//platform-specific global functions
|
||||
void alert(const char*, ...);
|
||||
void dprintf(const char*, ...);
|
||||
void dprintf(uint, const char*, ...);
|
||||
|
||||
namespace source {
|
||||
enum {
|
||||
none = 0,
|
||||
debug,
|
||||
cpu,
|
||||
ppu,
|
||||
smp,
|
||||
dsp,
|
||||
bus,
|
||||
};
|
||||
};
|
||||
|
||||
#include "interface.h"
|
||||
Binary file not shown.
@@ -82,6 +82,14 @@ void Cartridge::load_end() {
|
||||
memory::stBrom.write_protect(true);
|
||||
memory::stBram.write_protect(false);
|
||||
|
||||
char fn[PATH_MAX];
|
||||
strcpy(fn, cart.fn);
|
||||
modify_extension(fn, "cht");
|
||||
if(fexists(fn)) {
|
||||
cheat.clear();
|
||||
cheat.load(fn);
|
||||
}
|
||||
|
||||
cart.loaded = true;
|
||||
bus.load_cart();
|
||||
}
|
||||
@@ -106,6 +114,14 @@ bool Cartridge::unload() {
|
||||
safe_free(stB.rom);
|
||||
safe_free(stB.ram);
|
||||
|
||||
char fn[PATH_MAX];
|
||||
strcpy(fn, cart.fn);
|
||||
modify_extension(fn, "cht");
|
||||
if(cheat.count() > 0 || fexists(fn)) {
|
||||
cheat.save(fn);
|
||||
cheat.clear();
|
||||
}
|
||||
|
||||
cart.loaded = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
+42
-45
@@ -29,16 +29,16 @@ char* Cartridge::get_save_filename(const char *source, const char *extension) {
|
||||
|
||||
//override path with user-specified folder, if one was defined
|
||||
if(config::path.save != "") {
|
||||
stringarray part;
|
||||
lstring part;
|
||||
split(part, "/", savefn);
|
||||
string fn = config::path.save();
|
||||
string fn = (const char*)config::path.save;
|
||||
if(strend(fn, "/") == false) strcat(fn, "/");
|
||||
strcat(fn, part[count(part) - 1]);
|
||||
strcpy(savefn, fn);
|
||||
|
||||
//resolve relative path, if found
|
||||
if(strbegin(fn, "./") == true) {
|
||||
strltrim(fn, "./");
|
||||
ltrim(fn, "./");
|
||||
strcpy(savefn, config::path.base);
|
||||
strcat(savefn, fn);
|
||||
}
|
||||
@@ -50,53 +50,50 @@ char* Cartridge::get_save_filename(const char *source, const char *extension) {
|
||||
bool Cartridge::load_file(const char *fn, uint8 *&data, uint &size) {
|
||||
dprintf("* Loading \"%s\"...", fn);
|
||||
|
||||
if(fexists(fn) == false) {
|
||||
return false;
|
||||
}
|
||||
if(fexists(fn) == false) return false;
|
||||
|
||||
switch(Reader::detect(fn)) {
|
||||
default:
|
||||
case Reader::RF_NORMAL: {
|
||||
FileReader ff(fn);
|
||||
if(!ff.ready()) {
|
||||
alert("Error loading image file (%s)!", fn);
|
||||
return false;
|
||||
}
|
||||
size = ff.size();
|
||||
data = ff.read();
|
||||
} break;
|
||||
|
||||
case Reader::RF_NORMAL: {
|
||||
FileReader ff(fn);
|
||||
if(!ff.ready()) {
|
||||
alert("Error loading image file (%s)!", fn);
|
||||
return false;
|
||||
}
|
||||
size = ff.size();
|
||||
data = ff.read();
|
||||
} break;
|
||||
#ifdef GZIP_SUPPORT
|
||||
case Reader::RF_GZ: {
|
||||
GZReader gf(fn);
|
||||
if(!gf.ready()) {
|
||||
alert("Error loading image file (%s)!", fn);
|
||||
return false;
|
||||
}
|
||||
size = gf.size();
|
||||
data = gf.read();
|
||||
} break;
|
||||
|
||||
#ifdef GZIP_SUPPORT
|
||||
case Reader::RF_GZ: {
|
||||
GZReader gf(fn);
|
||||
if(!gf.ready()) {
|
||||
alert("Error loading image file (%s)!", fn);
|
||||
return false;
|
||||
}
|
||||
size = gf.size();
|
||||
data = gf.read();
|
||||
} break;
|
||||
|
||||
case Reader::RF_ZIP: {
|
||||
ZipReader zf(fn);
|
||||
size = zf.size();
|
||||
data = zf.read();
|
||||
} break;
|
||||
#endif
|
||||
|
||||
#ifdef JMA_SUPPORT
|
||||
case Reader::RF_JMA: {
|
||||
try {
|
||||
JMAReader jf(fn);
|
||||
size = jf.size();
|
||||
data = jf.read();
|
||||
} catch(JMA::jma_errors jma_error) {
|
||||
alert("Error loading image file (%s)!", fn);
|
||||
return false;
|
||||
}
|
||||
} break;
|
||||
#endif
|
||||
case Reader::RF_ZIP: {
|
||||
ZipReader zf(fn);
|
||||
size = zf.size();
|
||||
data = zf.read();
|
||||
} break;
|
||||
#endif
|
||||
|
||||
#ifdef JMA_SUPPORT
|
||||
case Reader::RF_JMA: {
|
||||
try {
|
||||
JMAReader jf(fn);
|
||||
size = jf.size();
|
||||
data = jf.read();
|
||||
} catch(JMA::jma_errors jma_error) {
|
||||
alert("Error loading image file (%s)!", fn);
|
||||
return false;
|
||||
}
|
||||
} break;
|
||||
#endif
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -28,7 +28,7 @@ uint size;
|
||||
memset(stA.ram, 0xff, stA.ram_size);
|
||||
|
||||
if(load_file(get_save_filename(stA.fn, "srm"), data, size) == true) {
|
||||
memcpy(stA.ram, data, min(size, 0x020000));
|
||||
memcpy(stA.ram, data, min(size, 0x020000U));
|
||||
safe_free(data);
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,7 @@ uint size;
|
||||
memset(stB.ram, 0xff, stB.ram_size);
|
||||
|
||||
if(load_file(get_save_filename(stB.fn, "srm"), data, size) == true) {
|
||||
memcpy(stB.ram, data, min(size, 0x020000));
|
||||
memcpy(stB.ram, data, min(size, 0x020000U));
|
||||
safe_free(data);
|
||||
}
|
||||
}
|
||||
|
||||
+3
-6
@@ -1,6 +1,3 @@
|
||||
@make -r PLATFORM=win-mingw-lui
|
||||
::@make -r PLATFORM=win-mingw-lui GZIP_SUPPORT=true JMA_SUPPORT=true
|
||||
::@make -r PLATFORM=win-visualc-lui
|
||||
::@make -r PLATFORM=win-visualc-lui GZIP_SUPPORT=true JMA_SUPPORT=true
|
||||
@move bsnes.exe ../bsnes.exe>nul
|
||||
@pause
|
||||
@make platform=win compiler=mingw32-gcc
|
||||
::@make platform=win compiler=mingw32-gcc enable_gzip=true enable_jma=true
|
||||
@pause
|
||||
@@ -1,3 +1,2 @@
|
||||
#!/bin/sh
|
||||
make PLATFORM=x-gcc-lui
|
||||
#make PLATFORM=x-gcc-lui GZIP_SUPPORT=true JMA_SUPPORT=true
|
||||
make platform=x compiler=gcc
|
||||
#make platform=x compiler=gcc enable_gzip=true enable_jma=true
|
||||
+31
-42
@@ -10,21 +10,21 @@ Cheat cheat;
|
||||
*****/
|
||||
|
||||
bool Cheat::decode(char *str, uint32 &addr, uint8 &data, uint8 &type) {
|
||||
stringarray t, part;
|
||||
string t, part;
|
||||
strcpy(t, str);
|
||||
strlower(t);
|
||||
if(strlen(t) == 8 || (strlen(t) == 9 && strptr(t)[6] == ':')) {
|
||||
strlower(t());
|
||||
if(strlen(t) == 8 || (strlen(t) == 9 && t()[6] == ':')) {
|
||||
type = CT_PRO_ACTION_REPLAY;
|
||||
replace(t, ":", "");
|
||||
uint32 r = strhex(t);
|
||||
uint32 r = strhex((const char*)t);
|
||||
addr = r >> 8;
|
||||
data = r & 0xff;
|
||||
return true;
|
||||
} else if(strlen(t) == 9 && strptr(t)[4] == '-') {
|
||||
} else if(strlen(t) == 9 && t()[4] == '-') {
|
||||
type = CT_GAME_GENIE;
|
||||
replace(t, "-", "");
|
||||
strtr(t, "df4709156bc8a23e", "0123456789abcdef");
|
||||
uint32 r = strhex(t);
|
||||
uint32 r = strhex((const char*)t);
|
||||
//8421 8421 8421 8421 8421 8421
|
||||
//abcd efgh ijkl mnop qrst uvwx
|
||||
//ijkl qrst opab cduv wxef ghmn
|
||||
@@ -269,51 +269,40 @@ void Cheat::disable(uint32 n) {
|
||||
* cheat file manipulation routines
|
||||
*****/
|
||||
|
||||
/* file format: */
|
||||
/* nnnn-nnnn = status, "description" \r\n */
|
||||
/* ... */
|
||||
|
||||
bool Cheat::load(const char *fn) {
|
||||
FileReader rf(fn);
|
||||
if(!rf.ready())return false;
|
||||
|
||||
uint8 *raw_data = rf.read();
|
||||
stringarray data, line;
|
||||
raw_data[rf.size()] = 0;
|
||||
strcpy(data, (char*)raw_data);
|
||||
safe_free(raw_data);
|
||||
string data;
|
||||
if(!fread(data, fn)) return false;
|
||||
replace(data, "\r\n", "\n");
|
||||
qreplace(data, "=", ",");
|
||||
qreplace(data, " ", "");
|
||||
|
||||
lstring line;
|
||||
split(line, "\n", data);
|
||||
for(int i = 0; i < ::count(line); i++) {
|
||||
stringarray part;
|
||||
uint8 en = *(strptr(line[i]));
|
||||
if(en == '+') {
|
||||
strltrim(line[i], "+");
|
||||
} else if(en == '-') {
|
||||
strltrim(line[i], "-");
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
qreplace(line[i], " ", "");
|
||||
qsplit(part, ",", line[i]);
|
||||
if(::count(part) != 2)continue;
|
||||
strunquote(part[1]);
|
||||
add(en == '+', strptr(part[0]), strptr(part[1]));
|
||||
lstring part;
|
||||
split(part, ",", line[i]);
|
||||
if(::count(part) != 3) continue;
|
||||
trim(part[2], "\"");
|
||||
add(part[1] == "enabled", part[0](), part[2]());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Cheat::save(const char *fn) {
|
||||
FileWriter wf(fn);
|
||||
if(!wf.ready())return false;
|
||||
|
||||
string data;
|
||||
char t[4096];
|
||||
strcpy(data, "");
|
||||
FILE *fp = fopen(fn, "wb");
|
||||
if(!fp) return false;
|
||||
for(int i = 0; i < cheat_count; i++) {
|
||||
sprintf(t, "%c%s, \"%s\"\r\n", index[i].enabled ? '+' : '-', index[i].code, index[i].desc);
|
||||
strcat(data, t);
|
||||
fprintf(fp, "%9s = %8s, \"%s\"\r\n",
|
||||
index[i].code,
|
||||
index[i].enabled ? "enabled" : "disabled",
|
||||
index[i].desc);
|
||||
}
|
||||
|
||||
wf.write((uint8*)strptr(data), strlen(data));
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -323,12 +312,12 @@ char t[4096];
|
||||
|
||||
void Cheat::clear() {
|
||||
cheat_enabled = false;
|
||||
cheat_count = 0;
|
||||
cheat_count = 0;
|
||||
memset(mask, 0, 0x200000);
|
||||
for(int i = 0; i < CHEAT_LIMIT + 1; i++) {
|
||||
for(int i = 0; i <= CHEAT_LIMIT; i++) {
|
||||
index[i].enabled = false;
|
||||
index[i].addr = 0x000000;
|
||||
index[i].data = 0x00;
|
||||
index[i].addr = 0x000000;
|
||||
index[i].data = 0x00;
|
||||
strcpy(index[i].code, "");
|
||||
strcpy(index[i].desc, "");
|
||||
}
|
||||
|
||||
+21
-18
@@ -2,18 +2,22 @@
|
||||
|
||||
class Cheat {
|
||||
public:
|
||||
enum { CT_PRO_ACTION_REPLAY, CT_GAME_GENIE };
|
||||
enum {
|
||||
CT_PRO_ACTION_REPLAY,
|
||||
CT_GAME_GENIE
|
||||
};
|
||||
|
||||
struct CheatIndex {
|
||||
bool enabled;
|
||||
uint32 addr;
|
||||
uint8 data;
|
||||
char code[ 16 + 1];
|
||||
char desc[128 + 1];
|
||||
} index[CHEAT_LIMIT + 1];
|
||||
bool cheat_enabled;
|
||||
uint32 cheat_count;
|
||||
uint8 mask[0x200000];
|
||||
struct CheatIndex {
|
||||
bool enabled;
|
||||
uint32 addr;
|
||||
uint8 data;
|
||||
char code[ 16 + 1];
|
||||
char desc[128 + 1];
|
||||
} index[CHEAT_LIMIT + 1];
|
||||
|
||||
bool cheat_enabled;
|
||||
uint32 cheat_count;
|
||||
uint8 mask[0x200000];
|
||||
|
||||
inline bool enabled() { return cheat_enabled; }
|
||||
inline uint count() { return cheat_count; }
|
||||
@@ -22,12 +26,6 @@ uint8 mask[0x200000];
|
||||
bool decode(char *str, uint32 &addr, uint8 &data, uint8 &type);
|
||||
bool encode(char *str, uint32 addr, uint8 data, uint8 type);
|
||||
|
||||
private:
|
||||
uint mirror_address(uint addr);
|
||||
void set(uint32 addr);
|
||||
void clear(uint32 addr);
|
||||
public:
|
||||
|
||||
bool read(uint32 addr, uint8 &data);
|
||||
|
||||
void update_cheat_status();
|
||||
@@ -42,7 +40,12 @@ public:
|
||||
bool save(const char *fn);
|
||||
void clear();
|
||||
|
||||
Cheat();
|
||||
Cheat();
|
||||
|
||||
private:
|
||||
uint mirror_address(uint addr);
|
||||
void set(uint32 addr);
|
||||
void clear(uint32 addr);
|
||||
};
|
||||
|
||||
extern Cheat cheat;
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "bsx/bsx.h"
|
||||
#include "superfx/superfx.h"
|
||||
#include "srtc/srtc.h"
|
||||
#include "sdd1/sdd1.h"
|
||||
#include "cx4/cx4.h"
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
void op_unknown() {}
|
||||
|
||||
void op_00();
|
||||
@@ -1,7 +0,0 @@
|
||||
//STOP
|
||||
void SuperFX::op_00() {
|
||||
regs.sfr.g = 0;
|
||||
regs.sfr.b = 0;
|
||||
regs.sfr.alt1 = 0;
|
||||
regs.sfr.alt2 = 0;
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
uint8 SuperFX::mmio_read(uint addr) {
|
||||
addr &= 0xffff;
|
||||
|
||||
switch(addr) {
|
||||
case 0x3000: return regs.r0.l;
|
||||
case 0x3001: return regs.r0.h;
|
||||
case 0x3002: return regs.r1.l;
|
||||
case 0x3003: return regs.r1.h;
|
||||
case 0x3004: return regs.r2.l;
|
||||
case 0x3005: return regs.r2.h;
|
||||
case 0x3006: return regs.r3.l;
|
||||
case 0x3007: return regs.r3.h;
|
||||
case 0x3008: return regs.r4.l;
|
||||
case 0x3009: return regs.r4.h;
|
||||
case 0x300a: return regs.r5.l;
|
||||
case 0x300b: return regs.r5.h;
|
||||
case 0x300c: return regs.r6.l;
|
||||
case 0x300d: return regs.r6.h;
|
||||
case 0x300e: return regs.r7.l;
|
||||
case 0x300f: return regs.r7.h;
|
||||
|
||||
case 0x3010: return regs.r8.l;
|
||||
case 0x3011: return regs.r8.h;
|
||||
case 0x3012: return regs.r9.l;
|
||||
case 0x3013: return regs.r9.h;
|
||||
case 0x3014: return regs.r10.l;
|
||||
case 0x3015: return regs.r10.h;
|
||||
case 0x3016: return regs.r11.l;
|
||||
case 0x3017: return regs.r11.h;
|
||||
case 0x3018: return regs.r12.l;
|
||||
case 0x3019: return regs.r12.h;
|
||||
case 0x301a: return regs.r13.l;
|
||||
case 0x301b: return regs.r13.h;
|
||||
case 0x301c: return regs.r14.l;
|
||||
case 0x301d: return regs.r14.h;
|
||||
case 0x301e: return regs.r15.l;
|
||||
case 0x301f: return regs.r15.h;
|
||||
|
||||
//0x3020 - 0x302f unused
|
||||
|
||||
case 0x3030: return regs.sfr;
|
||||
case 0x3031: return regs.sfr >> 8;
|
||||
case 0x3032: return 0x00; //unused
|
||||
case 0x3033: return 0x00; //BRAMR (write only)
|
||||
case 0x3034: return regs.pbr;
|
||||
case 0x3035: return 0x00; //unused
|
||||
case 0x3036: return regs.rombr;
|
||||
case 0x3037: return 0x00; //CFGR (write only)
|
||||
case 0x3038: return 0x00; //SCBR (write only)
|
||||
case 0x3039: return 0x00; //CLSR (write only)
|
||||
case 0x303a: return 0x00; //SCMR (write only)
|
||||
case 0x303b: return regs.vcr;
|
||||
case 0x303c: return regs.rambr;
|
||||
case 0x303d: return 0x00; //unused
|
||||
case 0x303e: return regs.cbr;
|
||||
case 0x303f: return regs.cbr >> 8;
|
||||
|
||||
//0x3040 - 0x30ff unused
|
||||
}
|
||||
|
||||
if(addr >= 0x3100 && addr <= 0x32ff) {
|
||||
return cache[addr - 0x3100];
|
||||
}
|
||||
|
||||
return 0x00;
|
||||
}
|
||||
@@ -1,65 +0,0 @@
|
||||
void SuperFX::mmio_write(uint addr, uint8 data) {
|
||||
addr &= 0xffff;
|
||||
|
||||
switch(addr) {
|
||||
case 0x3000: regs.r0.l = data; return;
|
||||
case 0x3001: regs.r0.h = data; return;
|
||||
case 0x3002: regs.r1.l = data; return;
|
||||
case 0x3003: regs.r1.h = data; return;
|
||||
case 0x3004: regs.r2.l = data; return;
|
||||
case 0x3005: regs.r2.h = data; return;
|
||||
case 0x3006: regs.r3.l = data; return;
|
||||
case 0x3007: regs.r3.h = data; return;
|
||||
case 0x3008: regs.r4.l = data; return;
|
||||
case 0x3009: regs.r4.h = data; return;
|
||||
case 0x300a: regs.r5.l = data; return;
|
||||
case 0x300b: regs.r5.h = data; return;
|
||||
case 0x300c: regs.r6.l = data; return;
|
||||
case 0x300d: regs.r6.h = data; return;
|
||||
case 0x300e: regs.r7.l = data; return;
|
||||
case 0x300f: regs.r7.h = data; return;
|
||||
|
||||
case 0x3010: regs.r8.l = data; return;
|
||||
case 0x3011: regs.r8.h = data; return;
|
||||
case 0x3012: regs.r9.l = data; return;
|
||||
case 0x3013: regs.r9.h = data; return;
|
||||
case 0x3014: regs.r10.l = data; return;
|
||||
case 0x3015: regs.r10.h = data; return;
|
||||
case 0x3016: regs.r11.l = data; return;
|
||||
case 0x3017: regs.r11.h = data; return;
|
||||
case 0x3018: regs.r12.l = data; return;
|
||||
case 0x3019: regs.r12.h = data; return;
|
||||
case 0x301a: regs.r13.l = data; return;
|
||||
case 0x301b: regs.r13.h = data; return;
|
||||
case 0x301c: regs.r14.l = data; return;
|
||||
case 0x301d: regs.r14.h = data; return;
|
||||
case 0x301e: regs.r15.l = data; return;
|
||||
case 0x301f: regs.r15.h = data; return;
|
||||
|
||||
//0x3020 - 0x302f unused
|
||||
|
||||
case 0x3030: regs.sfr.l = data & 0x7e; return; //mask invalid bits
|
||||
case 0x3031: regs.sfr.h = data & 0x9f; return; //mask invalid bits
|
||||
case 0x3032: return; //unused
|
||||
case 0x3033: regs.bramr = data; return;
|
||||
case 0x3034: regs.pbr = data; return;
|
||||
case 0x3035: return; //unused
|
||||
case 0x3036: return; //ROMBR (read only)
|
||||
case 0x3037: regs.cfgr = data; return;
|
||||
case 0x3038: regs.scbr = data; return;
|
||||
case 0x3039: regs.clsr = data; return;
|
||||
case 0x303a: regs.scmr = data; return;
|
||||
case 0x303b: return; //VCR (read only)
|
||||
case 0x303c: return; //RAMBR (read only)
|
||||
case 0x303d: return; //unused
|
||||
case 0x303e: return; //CBR low (read only)
|
||||
case 0x303f: return; //CBR high (read only)
|
||||
|
||||
//0x3040 - 0x30ff unused
|
||||
}
|
||||
|
||||
if(addr >= 0x3100 && addr <= 0x32ff) {
|
||||
cache[addr - 0x3100] = data;
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1,174 +0,0 @@
|
||||
struct Reg16 {
|
||||
union {
|
||||
uint16 w;
|
||||
struct { uint8 order_lsb2(l, h); };
|
||||
};
|
||||
|
||||
inline operator unsigned() const { return w; }
|
||||
inline unsigned operator=(const unsigned i) { return w = i; }
|
||||
|
||||
Reg16() : w(0) {}
|
||||
};
|
||||
|
||||
template<int bit> struct RegFlag8 {
|
||||
uint8 data;
|
||||
|
||||
inline operator bool() const { return data & bit; }
|
||||
inline bool operator=(const bool i) { i ? data |= bit : data &= ~bit; return i; }
|
||||
};
|
||||
|
||||
template<int bit> struct RegFlag16 {
|
||||
uint16 data;
|
||||
|
||||
inline operator bool() const { return data & bit; }
|
||||
inline bool operator=(const bool i) { i ? data |= bit : data &= ~bit; return i; }
|
||||
};
|
||||
|
||||
struct SFR {
|
||||
union {
|
||||
uint16 w;
|
||||
struct { uint8 order_lsb2(l, h); };
|
||||
RegFlag16<0x0002> z; //zero flag
|
||||
RegFlag16<0x0004> c; //carry flag
|
||||
RegFlag16<0x0008> s; //sign flag
|
||||
RegFlag16<0x0010> v; //overflow flag
|
||||
RegFlag16<0x0020> g; //go flag
|
||||
RegFlag16<0x0040> r; //ROM read using r14 flag
|
||||
RegFlag16<0x0100> alt1; //alternate instruction 1 flag
|
||||
RegFlag16<0x0200> alt2; //alternate instruction 2 flag
|
||||
RegFlag16<0x0400> il; //immediate lower 8-bit flag
|
||||
RegFlag16<0x0800> ih; //immediate upper 8-bit flag
|
||||
RegFlag16<0x1000> b; //WITH instruction flag
|
||||
RegFlag16<0x8000> irq; //interrupt flag
|
||||
};
|
||||
|
||||
inline operator unsigned() const { return w & 0x9f7e; } //invalid flag bits always return 0 when read
|
||||
inline unsigned operator=(const unsigned i) { return w = i & 0x9f7e; }
|
||||
|
||||
SFR() : w(0) {}
|
||||
};
|
||||
|
||||
struct RAMBR {
|
||||
union {
|
||||
uint8 b;
|
||||
RegFlag8<0x01> bank;
|
||||
};
|
||||
|
||||
inline operator unsigned() const { return b & 0x01; }
|
||||
inline unsigned operator=(const unsigned i) { return b = i & 0x01; }
|
||||
|
||||
RAMBR() : b(0) {}
|
||||
};
|
||||
|
||||
struct CBR {
|
||||
uint16 w;
|
||||
|
||||
inline operator unsigned() const { return w & 0xfff0; }
|
||||
inline unsigned operator=(const unsigned i) { return w = i & 0xfff0; }
|
||||
|
||||
CBR() : w(0) {}
|
||||
};
|
||||
|
||||
struct SCMR {
|
||||
union {
|
||||
uint8 b;
|
||||
RegFlag8<0x01> md0; //color mode low
|
||||
RegFlag8<0x02> md1; //color mode high
|
||||
RegFlag8<0x04> ht0; //height low
|
||||
RegFlag8<0x08> ran; //ram enable
|
||||
RegFlag8<0x10> ron; //rom enable
|
||||
RegFlag8<0x20> ht1; //height high
|
||||
};
|
||||
|
||||
inline operator unsigned() const { return b; }
|
||||
inline unsigned operator=(const unsigned i) { return b = i; }
|
||||
|
||||
SCMR() : b(0) {}
|
||||
};
|
||||
|
||||
struct BRAMR {
|
||||
union {
|
||||
uint8 b;
|
||||
RegFlag8<0x01> flag;
|
||||
};
|
||||
|
||||
inline operator unsigned() const { return b; }
|
||||
inline unsigned operator=(const unsigned i) { return b = i; }
|
||||
|
||||
BRAMR() : b(0) {}
|
||||
};
|
||||
|
||||
struct CFGR {
|
||||
union {
|
||||
uint8 b;
|
||||
RegFlag8<0x20> ms0; //multiplier speed selection
|
||||
RegFlag8<0x80> irq; //irq mask flag
|
||||
};
|
||||
|
||||
inline operator unsigned() const { return b; }
|
||||
inline unsigned operator=(const unsigned i) { return b = i; }
|
||||
|
||||
CFGR() : b(0) {}
|
||||
};
|
||||
|
||||
struct CLSR {
|
||||
union {
|
||||
uint8 b;
|
||||
RegFlag8<0x01> flag;
|
||||
};
|
||||
|
||||
inline operator unsigned() const { return b; }
|
||||
inline unsigned operator=(const unsigned i) { return b = i; }
|
||||
|
||||
CLSR() : b(0) {}
|
||||
};
|
||||
|
||||
struct POR {
|
||||
union {
|
||||
uint8 b;
|
||||
RegFlag8<0x01> transparent; //transparent flag
|
||||
RegFlag8<0x02> dither; //dither flag
|
||||
RegFlag8<0x04> highnibble; //high nibble flag
|
||||
RegFlag8<0x08> freezehigh; //freeze high flag
|
||||
RegFlag8<0x10> obj; //OBJ flag
|
||||
};
|
||||
|
||||
inline operator unsigned() const { return b; }
|
||||
inline unsigned operator=(const unsigned i) { return b = i; }
|
||||
|
||||
POR() : b(0) {}
|
||||
};
|
||||
|
||||
struct Regs {
|
||||
Reg16 r0; //default source/destination register
|
||||
Reg16 r1; //pixel plot X position register
|
||||
Reg16 r2; //pixel plot Y position register
|
||||
Reg16 r3;
|
||||
Reg16 r4; //lower 16-bit result of lmult
|
||||
Reg16 r5;
|
||||
Reg16 r6; //multiplier for fmult and lmult
|
||||
Reg16 r7; //fixed point texel X position for merge
|
||||
Reg16 r8; //fixed point texel Y position for merge
|
||||
Reg16 r9;
|
||||
Reg16 r10;
|
||||
Reg16 r11; //return address set by link
|
||||
Reg16 r12; //loop counter
|
||||
Reg16 r13; //loop point address
|
||||
Reg16 r14; //rom address for getb, getbh, getbl, getbs
|
||||
Reg16 r15; //program counter
|
||||
|
||||
SFR sfr; //status/flag register
|
||||
uint8 pbr; //program bank register
|
||||
uint8 rombr; //rom bank register
|
||||
RAMBR rambr; //ram bank register
|
||||
CBR cbr; //cache base register
|
||||
uint8 scbr; //screen base register
|
||||
SCMR scmr; //screen mode register
|
||||
BRAMR bramr; //backup ram register
|
||||
uint8 vcr; //version code register
|
||||
CFGR cfgr; //config register
|
||||
CLSR clsr; //clock select register
|
||||
|
||||
uint8 colr; //color register
|
||||
POR por; //plot option register
|
||||
} regs;
|
||||
@@ -1,42 +0,0 @@
|
||||
#include "../../base.h"
|
||||
|
||||
#include "core/op0x.cpp"
|
||||
|
||||
#include "memory/read.cpp"
|
||||
#include "memory/write.cpp"
|
||||
|
||||
void SuperFX::init() {
|
||||
}
|
||||
|
||||
void SuperFX::enable() {
|
||||
for(uint i = 0x3000; i <= 0x32ff; i++) {
|
||||
memory::mmio.map(i, *this);
|
||||
}
|
||||
}
|
||||
|
||||
void SuperFX::power() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void SuperFX::reset() {
|
||||
regs.r0 = 0;
|
||||
regs.r1 = 0;
|
||||
regs.r2 = 0;
|
||||
regs.r3 = 0;
|
||||
regs.r4 = 0;
|
||||
regs.r5 = 0;
|
||||
regs.r6 = 0;
|
||||
regs.r7 = 0;
|
||||
regs.r8 = 0;
|
||||
regs.r9 = 0;
|
||||
regs.r10 = 0;
|
||||
regs.r11 = 0;
|
||||
regs.r12 = 0;
|
||||
regs.r13 = 0;
|
||||
regs.r14 = 0;
|
||||
regs.r15 = 0;
|
||||
|
||||
regs.sfr = 0;
|
||||
|
||||
memset(cache, 0, sizeof cache);
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
class SuperFX : public MMIO { public:
|
||||
#include "core/core.h"
|
||||
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
uint8 mmio_read (uint addr);
|
||||
void mmio_write(uint addr, uint8 data);
|
||||
|
||||
private:
|
||||
#include "regs.h"
|
||||
uint8 cache[512]; //cache RAM
|
||||
};
|
||||
|
||||
extern SuperFX superfx;
|
||||
+1
-2
@@ -1,2 +1 @@
|
||||
@make PLATFORM=win-mingw-lui clean
|
||||
::@make PLATFORM=win-visualc-lui clean
|
||||
@make platform=win compiler=mingw32-gcc clean
|
||||
+1
-2
@@ -1,2 +1 @@
|
||||
#!/bin/sh
|
||||
make PLATFORM=x-gcc-lui clean
|
||||
make platform=x compiler=gcc clean
|
||||
+62
-65
@@ -1,7 +1,7 @@
|
||||
namespace config {
|
||||
|
||||
Config& config() {
|
||||
static Config config;
|
||||
configuration& config() {
|
||||
static configuration config;
|
||||
return config;
|
||||
}
|
||||
|
||||
@@ -15,61 +15,58 @@ string path(req_path);
|
||||
if(!strend(path, "/")) { strcat(path, "/"); }
|
||||
|
||||
if(strbegin(path, "./")) {
|
||||
strltrim(path, "./");
|
||||
ltrim(path(), "./");
|
||||
string temp;
|
||||
strcpy(temp, config::path.base);
|
||||
strcat(temp, path);
|
||||
strcpy(path, temp);
|
||||
}
|
||||
|
||||
stringarray part;
|
||||
lstring part;
|
||||
split(part, "/", file);
|
||||
strcat(path, part[count(part) - 1]);
|
||||
return path;
|
||||
}
|
||||
|
||||
StringSetting Path::base(0, "path.base",
|
||||
string_setting Path::base("path.base",
|
||||
"Path that bsnes resides in", "");
|
||||
StringSetting Path::rom(&config(), "path.rom",
|
||||
string_setting Path::rom(config(), "path.rom",
|
||||
"Default path to look for ROM files in (\"\" = use default directory)", "");
|
||||
StringSetting Path::save(&config(), "path.save",
|
||||
string_setting Path::save(config(), "path.save",
|
||||
"Default path for all save RAM and cheat files (\"\" = use current directory)", "");
|
||||
StringSetting Path::bsx(&config(), "path.bsx", "", "");
|
||||
StringSetting Path::st(&config(), "path.st", "", "");
|
||||
string_setting Path::bsx(config(), "path.bsx", "", "");
|
||||
string_setting Path::st(config(), "path.st", "", "");
|
||||
|
||||
IntegerSetting SNES::gamma_ramp(&config(), "snes.colorfilter.gamma_ramp",
|
||||
"Use precalculated TV-style gamma ramp", IntegerSetting::Boolean, true);
|
||||
IntegerSetting SNES::sepia(&config(), "snes.colorfilter.sepia",
|
||||
"Convert color to sepia tone", IntegerSetting::Boolean, false);
|
||||
IntegerSetting SNES::grayscale(&config(), "snes.colorfilter.grayscale",
|
||||
"Convert color to grayscale tone", IntegerSetting::Boolean, false);
|
||||
IntegerSetting SNES::invert(&config(), "snes.colorfilter.invert",
|
||||
"Invert output image colors", IntegerSetting::Boolean, false);
|
||||
IntegerSetting SNES::contrast(&config(), "snes.colorfilter.contrast",
|
||||
"Contrast", IntegerSetting::Decimal, 0);
|
||||
IntegerSetting SNES::brightness(&config(), "snes.colorfilter.brightness",
|
||||
"Brightness", IntegerSetting::Decimal, 0);
|
||||
IntegerSetting SNES::gamma(&config(), "snes.colorfilter.gamma",
|
||||
"Gamma", IntegerSetting::Decimal, 80);
|
||||
integral_setting SNES::gamma_ramp(config(), "snes.colorfilter.gamma_ramp",
|
||||
"Use precalculated TV-style gamma ramp", integral_setting::boolean, true);
|
||||
integral_setting SNES::sepia(config(), "snes.colorfilter.sepia",
|
||||
"Convert color to sepia tone", integral_setting::boolean, false);
|
||||
integral_setting SNES::grayscale(config(), "snes.colorfilter.grayscale",
|
||||
"Convert color to grayscale tone", integral_setting::boolean, false);
|
||||
integral_setting SNES::invert(config(), "snes.colorfilter.invert",
|
||||
"Invert output image colors", integral_setting::boolean, false);
|
||||
integral_setting SNES::contrast(config(), "snes.colorfilter.contrast",
|
||||
"Contrast", integral_setting::decimal, 0);
|
||||
integral_setting SNES::brightness(config(), "snes.colorfilter.brightness",
|
||||
"Brightness", integral_setting::decimal, 0);
|
||||
integral_setting SNES::gamma(config(), "snes.colorfilter.gamma",
|
||||
"Gamma", integral_setting::decimal, 80);
|
||||
|
||||
IntegerSetting SNES::ntsc_merge_fields(&config(), "snes.ntsc_merge_fields",
|
||||
integral_setting SNES::ntsc_merge_fields(config(), "snes.ntsc_merge_fields",
|
||||
"Merge fields in NTSC video filter\n"
|
||||
"Set to true if using filter at any refresh rate other than 60hz\n"
|
||||
"", IntegerSetting::Boolean, true);
|
||||
"", integral_setting::boolean, true);
|
||||
|
||||
IntegerSetting SNES::mute(&config(), "snes.mute", "Mutes SNES audio output when enabled",
|
||||
IntegerSetting::Boolean, false);
|
||||
integral_setting SNES::controller_port0(config(), "snes.controller_port_1",
|
||||
"Controller attached to SNES port 1", integral_setting::decimal, ::SNES::DEVICEID_JOYPAD1);
|
||||
integral_setting SNES::controller_port1(config(), "snes.controller_port_2",
|
||||
"Controller attached to SNES port 2", integral_setting::decimal, ::SNES::DEVICEID_JOYPAD2);
|
||||
|
||||
IntegerSetting SNES::controller_port0(&config(), "snes.controller_port_1",
|
||||
"Controller attached to SNES port 1", IntegerSetting::Decimal, ::SNES::DEVICEID_JOYPAD1);
|
||||
IntegerSetting SNES::controller_port1(&config(), "snes.controller_port_2",
|
||||
"Controller attached to SNES port 2", IntegerSetting::Decimal, ::SNES::DEVICEID_JOYPAD2);
|
||||
|
||||
IntegerSetting CPU::ntsc_clock_rate(&config(), "cpu.ntsc_clock_rate",
|
||||
"NTSC S-CPU clock rate (in hz)", IntegerSetting::Decimal, 21477272);
|
||||
IntegerSetting CPU::pal_clock_rate(&config(), "cpu.pal_clock_rate",
|
||||
"PAL S-CPU clock rate (in hz)", IntegerSetting::Decimal, 21281370);
|
||||
IntegerSetting CPU::wram_init_value(&config(), "cpu.wram_init_value",
|
||||
integral_setting CPU::ntsc_clock_rate(config(), "cpu.ntsc_clock_rate",
|
||||
"NTSC S-CPU clock rate (in hz)", integral_setting::decimal, 21477272);
|
||||
integral_setting CPU::pal_clock_rate(config(), "cpu.pal_clock_rate",
|
||||
"PAL S-CPU clock rate (in hz)", integral_setting::decimal, 21281370);
|
||||
integral_setting CPU::wram_init_value(config(), "cpu.wram_init_value",
|
||||
"Value to initialize 128k WRAM to upon power cycle.\n"
|
||||
"Note that on real hardware, this value is undefined; meaning it can vary\n"
|
||||
"per power-on, and per SNES unit. Such randomness is undesirable for an\n"
|
||||
@@ -81,52 +78,52 @@ IntegerSetting CPU::wram_init_value(&config(), "cpu.wram_init_value",
|
||||
"which executed on these copiers. Using 0x00 will therefore fix many homebrew\n"
|
||||
"programs, but *will* break some poorly programmed commercial software titles,\n"
|
||||
"which do not properly initialize WRAM upon power cycle.\n",
|
||||
IntegerSetting::Hex, 0x55);
|
||||
integral_setting::hex, 0x55);
|
||||
|
||||
IntegerSetting CPU::hdma_enable(0, "cpu.hdma_enable",
|
||||
"Enable HDMA effects", IntegerSetting::Boolean, true);
|
||||
integral_setting CPU::hdma_enable("cpu.hdma_enable",
|
||||
"Enable HDMA effects", integral_setting::boolean, true);
|
||||
|
||||
IntegerSetting SMP::ntsc_clock_rate(&config(), "smp.ntsc_clock_rate",
|
||||
"NTSC S-SMP clock rate (in hz)", IntegerSetting::Decimal, 24606720);
|
||||
IntegerSetting SMP::pal_clock_rate(&config(), "smp.pal_clock_rate",
|
||||
"PAL S-SMP clock rate (in hz)", IntegerSetting::Decimal, 24606720);
|
||||
integral_setting SMP::ntsc_clock_rate(config(), "smp.ntsc_clock_rate",
|
||||
"NTSC S-SMP clock rate (in hz)", integral_setting::decimal, 24606720);
|
||||
integral_setting SMP::pal_clock_rate(config(), "smp.pal_clock_rate",
|
||||
"PAL S-SMP clock rate (in hz)", integral_setting::decimal, 24606720);
|
||||
|
||||
IntegerSetting PPU::Hack::render_scanline_position(&config(), "ppu.hack.render_scanline_position",
|
||||
integral_setting PPU::Hack::render_scanline_position(config(), "ppu.hack.render_scanline_position",
|
||||
"Approximate HCLOCK position to render at for scanline-based renderers",
|
||||
IntegerSetting::Decimal, 512);
|
||||
IntegerSetting PPU::Hack::obj_cache(&config(), "ppu.hack.obj_cache",
|
||||
integral_setting::decimal, 512);
|
||||
integral_setting PPU::Hack::obj_cache(config(), "ppu.hack.obj_cache",
|
||||
"Cache OAM OBJ attributes one scanline before rendering\n"
|
||||
"This is technically closer to the actual operation of the SNES,\n"
|
||||
"but can cause problems in some games if enabled",
|
||||
IntegerSetting::Boolean, false);
|
||||
IntegerSetting PPU::Hack::oam_address_invalidation(&config(), "ppu.hack.oam_address_invalidation",
|
||||
integral_setting::boolean, false);
|
||||
integral_setting PPU::Hack::oam_address_invalidation(config(), "ppu.hack.oam_address_invalidation",
|
||||
"OAM access address changes during active display, as the S-PPU reads\n"
|
||||
"data to render the display. Thusly, the address retrieved when accessing\n"
|
||||
"OAM during active display is unpredictable. Unfortunately, the exact\n"
|
||||
"algorithm for this is completely unknown at this time. It is more hardware\n"
|
||||
"accurate to enable this setting, but one must *not* rely on the actual\n"
|
||||
"address to match hardware under emulation.",
|
||||
IntegerSetting::Boolean, true);
|
||||
IntegerSetting PPU::Hack::cgram_address_invalidation(&config(), "ppu.hack.cgram_address_invalidation",
|
||||
integral_setting::boolean, true);
|
||||
integral_setting PPU::Hack::cgram_address_invalidation(config(), "ppu.hack.cgram_address_invalidation",
|
||||
"CGRAM access address changes during active display (excluding hblank), as\n"
|
||||
"the S-PPU reads data to render the display. Thusly, as with OAM, the access\n"
|
||||
"address is unpredictable. Again, enabling this setting is more hardware\n"
|
||||
"accurate, but one must *not* rely on the actual address to match hardware\n"
|
||||
"under emulation.",
|
||||
IntegerSetting::Boolean, true);
|
||||
integral_setting::boolean, true);
|
||||
|
||||
IntegerSetting PPU::opt_enable(0, "ppu.opt_enable", "Enable offset-per-tile effects", IntegerSetting::Boolean, true);
|
||||
IntegerSetting PPU::bg1_pri0_enable(0, "ppu.bg1_pri0_enable", "Enable BG1 Priority 0", IntegerSetting::Boolean, true);
|
||||
IntegerSetting PPU::bg1_pri1_enable(0, "ppu.bg1_pri1_enable", "Enable BG1 Priority 1", IntegerSetting::Boolean, true);
|
||||
IntegerSetting PPU::bg2_pri0_enable(0, "ppu.bg2_pri0_enable", "Enable BG2 Priority 0", IntegerSetting::Boolean, true);
|
||||
IntegerSetting PPU::bg2_pri1_enable(0, "ppu.bg2_pri1_enable", "Enable BG2 Priority 1", IntegerSetting::Boolean, true);
|
||||
IntegerSetting PPU::bg3_pri0_enable(0, "ppu.bg3_pri0_enable", "Enable BG3 Priority 0", IntegerSetting::Boolean, true);
|
||||
IntegerSetting PPU::bg3_pri1_enable(0, "ppu.bg3_pri1_enable", "Enable BG3 Priority 1", IntegerSetting::Boolean, true);
|
||||
IntegerSetting PPU::bg4_pri0_enable(0, "ppu.bg4_pri0_enable", "Enable BG4 Priority 0", IntegerSetting::Boolean, true);
|
||||
IntegerSetting PPU::bg4_pri1_enable(0, "ppu.bg4_pri1_enable", "Enable BG4 Priority 1", IntegerSetting::Boolean, true);
|
||||
IntegerSetting PPU::oam_pri0_enable(0, "ppu.oam_pri0_enable", "Enable OAM Priority 0", IntegerSetting::Boolean, true);
|
||||
IntegerSetting PPU::oam_pri1_enable(0, "ppu.oam_pri1_enable", "Enable OAM Priority 1", IntegerSetting::Boolean, true);
|
||||
IntegerSetting PPU::oam_pri2_enable(0, "ppu.oam_pri2_enable", "Enable OAM Priority 2", IntegerSetting::Boolean, true);
|
||||
IntegerSetting PPU::oam_pri3_enable(0, "ppu.oam_pri3_enable", "Enable OAM Priority 3", IntegerSetting::Boolean, true);
|
||||
integral_setting PPU::opt_enable("ppu.opt_enable", "Enable offset-per-tile effects", integral_setting::boolean, true);
|
||||
integral_setting PPU::bg1_pri0_enable("ppu.bg1_pri0_enable", "Enable BG1 Priority 0", integral_setting::boolean, true);
|
||||
integral_setting PPU::bg1_pri1_enable("ppu.bg1_pri1_enable", "Enable BG1 Priority 1", integral_setting::boolean, true);
|
||||
integral_setting PPU::bg2_pri0_enable("ppu.bg2_pri0_enable", "Enable BG2 Priority 0", integral_setting::boolean, true);
|
||||
integral_setting PPU::bg2_pri1_enable("ppu.bg2_pri1_enable", "Enable BG2 Priority 1", integral_setting::boolean, true);
|
||||
integral_setting PPU::bg3_pri0_enable("ppu.bg3_pri0_enable", "Enable BG3 Priority 0", integral_setting::boolean, true);
|
||||
integral_setting PPU::bg3_pri1_enable("ppu.bg3_pri1_enable", "Enable BG3 Priority 1", integral_setting::boolean, true);
|
||||
integral_setting PPU::bg4_pri0_enable("ppu.bg4_pri0_enable", "Enable BG4 Priority 0", integral_setting::boolean, true);
|
||||
integral_setting PPU::bg4_pri1_enable("ppu.bg4_pri1_enable", "Enable BG4 Priority 1", integral_setting::boolean, true);
|
||||
integral_setting PPU::oam_pri0_enable("ppu.oam_pri0_enable", "Enable OAM Priority 0", integral_setting::boolean, true);
|
||||
integral_setting PPU::oam_pri1_enable("ppu.oam_pri1_enable", "Enable OAM Priority 1", integral_setting::boolean, true);
|
||||
integral_setting PPU::oam_pri2_enable("ppu.oam_pri2_enable", "Enable OAM Priority 2", integral_setting::boolean, true);
|
||||
integral_setting PPU::oam_pri3_enable("ppu.oam_pri3_enable", "Enable OAM Priority 3", integral_setting::boolean, true);
|
||||
|
||||
};
|
||||
+22
-23
@@ -1,47 +1,46 @@
|
||||
namespace config {
|
||||
|
||||
extern Config& config();
|
||||
extern configuration& config();
|
||||
|
||||
string file_updatepath(const char *, const char *);
|
||||
|
||||
extern struct Path {
|
||||
static StringSetting base, rom, save;
|
||||
static StringSetting bsx, st;
|
||||
static string_setting base, rom, save;
|
||||
static string_setting bsx, st;
|
||||
} path;
|
||||
|
||||
extern struct SNES {
|
||||
static IntegerSetting gamma_ramp, sepia, grayscale, invert, contrast, brightness, gamma;
|
||||
static IntegerSetting ntsc_merge_fields;
|
||||
static IntegerSetting mute;
|
||||
static IntegerSetting controller_port0;
|
||||
static IntegerSetting controller_port1;
|
||||
static integral_setting gamma_ramp, sepia, grayscale, invert, contrast, brightness, gamma;
|
||||
static integral_setting ntsc_merge_fields;
|
||||
static integral_setting controller_port0;
|
||||
static integral_setting controller_port1;
|
||||
} snes;
|
||||
|
||||
extern struct CPU {
|
||||
static IntegerSetting ntsc_clock_rate, pal_clock_rate;
|
||||
static IntegerSetting wram_init_value;
|
||||
static IntegerSetting hdma_enable;
|
||||
static integral_setting ntsc_clock_rate, pal_clock_rate;
|
||||
static integral_setting wram_init_value;
|
||||
static integral_setting hdma_enable;
|
||||
} cpu;
|
||||
|
||||
extern struct SMP {
|
||||
static IntegerSetting ntsc_clock_rate, pal_clock_rate;
|
||||
static integral_setting ntsc_clock_rate, pal_clock_rate;
|
||||
} smp;
|
||||
|
||||
extern struct PPU {
|
||||
struct Hack {
|
||||
static IntegerSetting render_scanline_position;
|
||||
static IntegerSetting obj_cache;
|
||||
static IntegerSetting oam_address_invalidation;
|
||||
static IntegerSetting cgram_address_invalidation;
|
||||
static integral_setting render_scanline_position;
|
||||
static integral_setting obj_cache;
|
||||
static integral_setting oam_address_invalidation;
|
||||
static integral_setting cgram_address_invalidation;
|
||||
} hack;
|
||||
|
||||
static IntegerSetting opt_enable;
|
||||
static IntegerSetting bg1_pri0_enable, bg1_pri1_enable;
|
||||
static IntegerSetting bg2_pri0_enable, bg2_pri1_enable;
|
||||
static IntegerSetting bg3_pri0_enable, bg3_pri1_enable;
|
||||
static IntegerSetting bg4_pri0_enable, bg4_pri1_enable;
|
||||
static IntegerSetting oam_pri0_enable, oam_pri1_enable;
|
||||
static IntegerSetting oam_pri2_enable, oam_pri3_enable;
|
||||
static integral_setting opt_enable;
|
||||
static integral_setting bg1_pri0_enable, bg1_pri1_enable;
|
||||
static integral_setting bg2_pri0_enable, bg2_pri1_enable;
|
||||
static integral_setting bg3_pri0_enable, bg3_pri1_enable;
|
||||
static integral_setting bg4_pri0_enable, bg4_pri1_enable;
|
||||
static integral_setting oam_pri0_enable, oam_pri1_enable;
|
||||
static integral_setting oam_pri2_enable, oam_pri3_enable;
|
||||
} ppu;
|
||||
|
||||
};
|
||||
Vendored
-5
@@ -1,5 +0,0 @@
|
||||
#!/bin/sh
|
||||
echo "Warning: bsnes does not use a configure script"
|
||||
echo "To compile bsnes, use make ..."
|
||||
echo ""
|
||||
make #prints make usage instructions
|
||||
@@ -250,7 +250,7 @@ void sCPU::timing_reset() {
|
||||
status.prev_line_clocks = 1364;
|
||||
|
||||
status.line_rendered = false;
|
||||
status.line_render_position = min(1112, (uint16)config::ppu.hack.render_scanline_position);
|
||||
status.line_render_position = min(1112U, (uint)config::ppu.hack.render_scanline_position);
|
||||
|
||||
status.dram_refreshed = false;
|
||||
status.dram_refresh_position = (cpu_version == 1) ? 530 : 538;
|
||||
|
||||
Binary file not shown.
+36
-36
@@ -1,36 +1,36 @@
|
||||
#include "memory/memory.h"
|
||||
#include "memory/smemory/smemory.h"
|
||||
|
||||
#include "cpu/cpu.h"
|
||||
#include "cpu/scpu/scpu.h"
|
||||
|
||||
#include "smp/smp.h"
|
||||
#include "smp/ssmp/ssmp.h"
|
||||
|
||||
#include "dsp/dsp.h"
|
||||
//#include "dsp/adsp/adsp.h"
|
||||
#include "dsp/bdsp/bdsp.h"
|
||||
|
||||
#include "ppu/ppu.h"
|
||||
#include "ppu/bppu/bppu.h"
|
||||
|
||||
#include "snes/snes.h"
|
||||
#include "chip/chip.h"
|
||||
|
||||
#include "reader/reader.h"
|
||||
#include "cart/cart.h"
|
||||
#include "cheat/cheat.h"
|
||||
#include "config/config.h"
|
||||
|
||||
#ifdef INTERFACE_MAIN
|
||||
#include "config/config.cpp"
|
||||
#define extern
|
||||
#endif
|
||||
|
||||
extern BUSCORE bus;
|
||||
extern CPUCORE cpu;
|
||||
extern SMPCORE smp;
|
||||
extern DSPCORE dsp;
|
||||
extern PPUCORE ppu;
|
||||
|
||||
#undef extern
|
||||
#include "reader/reader.h"
|
||||
#include "cheat/cheat.h"
|
||||
#include "config/config.h"
|
||||
|
||||
#include "memory/memory.h"
|
||||
#include "memory/smemory/smemory.h"
|
||||
|
||||
#include "cart/cart.h"
|
||||
|
||||
#include "cpu/cpu.h"
|
||||
#include "cpu/scpu/scpu.h"
|
||||
|
||||
#include "smp/smp.h"
|
||||
#include "smp/ssmp/ssmp.h"
|
||||
|
||||
#include "dsp/dsp.h"
|
||||
#include "dsp/bdsp/bdsp.h"
|
||||
|
||||
#include "ppu/ppu.h"
|
||||
#include "ppu/bppu/bppu.h"
|
||||
|
||||
#include "snes/snes.h"
|
||||
#include "chip/chip.h"
|
||||
|
||||
#ifdef INTERFACE_MAIN
|
||||
#include "config/config.cpp"
|
||||
#define extern
|
||||
#endif
|
||||
|
||||
extern BUSCORE bus;
|
||||
extern CPUCORE cpu;
|
||||
extern SMPCORE smp;
|
||||
extern DSPCORE dsp;
|
||||
extern PPUCORE ppu;
|
||||
|
||||
#undef extern
|
||||
@@ -1,14 +1,28 @@
|
||||
/*
|
||||
libbase : version 0.11a ~byuu (2007-10-14)
|
||||
bbase : version 0.12 ~byuu (2007-12-12)
|
||||
license: public domain
|
||||
*/
|
||||
|
||||
#ifndef LIBBASE_H
|
||||
#define LIBBASE_H
|
||||
#ifndef BBASE_H
|
||||
#define BBASE_H
|
||||
|
||||
#include <nall/stdint.hpp>
|
||||
typedef int8_t int8;
|
||||
typedef int16_t int16;
|
||||
typedef int32_t int32;
|
||||
typedef int64_t int64;
|
||||
typedef uint8_t uint8;
|
||||
typedef uint16_t uint16;
|
||||
typedef uint32_t uint32;
|
||||
typedef uint64_t uint64;
|
||||
typedef unsigned int uint;
|
||||
|
||||
#include <algorithm>
|
||||
using std::min;
|
||||
using std::max;
|
||||
|
||||
#include <assert.h>
|
||||
#include <limits.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
@@ -16,8 +30,6 @@
|
||||
#include <time.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <new>
|
||||
|
||||
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||
#include <io.h>
|
||||
#include <direct.h>
|
||||
@@ -70,22 +82,6 @@
|
||||
#define alwaysinline inline
|
||||
#endif
|
||||
|
||||
/*****
|
||||
* typedefs
|
||||
*****/
|
||||
|
||||
typedef unsigned int uint;
|
||||
|
||||
typedef uint8_t uint8;
|
||||
typedef uint16_t uint16;
|
||||
typedef uint32_t uint32;
|
||||
typedef uint64_t uint64;
|
||||
|
||||
typedef int8_t int8;
|
||||
typedef int16_t int16;
|
||||
typedef int32_t int32;
|
||||
typedef int64_t int64;
|
||||
|
||||
/*****
|
||||
* OS localization
|
||||
*****/
|
||||
@@ -109,7 +105,7 @@ struct passwd *userinfo = getpwuid(getuid());
|
||||
#endif
|
||||
|
||||
/*****
|
||||
* templates
|
||||
* template functions
|
||||
*****/
|
||||
|
||||
template<typename T> inline void safe_free(T &handle) {
|
||||
@@ -133,88 +129,57 @@ template<typename T> inline void safe_release(T &handle) {
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T> inline void swap(T &x, T &y) {
|
||||
T z = x;
|
||||
x = y;
|
||||
y = z;
|
||||
}
|
||||
|
||||
#undef min
|
||||
#define min(x, y) (((x) < (y)) ? (x) : (y))
|
||||
|
||||
#undef max
|
||||
#define max(x, y) (((x) > (y)) ? (x) : (y))
|
||||
|
||||
template<int min, int max, typename T> inline T minmax(const T x) {
|
||||
return (x < (T)min) ? (T)min : (x > (T)max) ? (T)max : x;
|
||||
}
|
||||
|
||||
template<int bits> inline unsigned uclamp(const unsigned x) {
|
||||
enum { y = (1U << bits) - 1 };
|
||||
return y + ((x - y) & -(x < y)); //min(x, y);
|
||||
}
|
||||
|
||||
template<int bits> inline unsigned uclip(const unsigned x) {
|
||||
enum { m = (1U << bits) - 1 };
|
||||
return (x & m);
|
||||
}
|
||||
|
||||
template<int bits> inline signed sclamp(const signed x) {
|
||||
enum { b = 1U << (bits - 1), m = (1U << (bits - 1)) - 1 };
|
||||
return (x > m) ? m : (x < -b) ? -b : x;
|
||||
}
|
||||
|
||||
template<int bits> inline signed sclip(const signed x) {
|
||||
enum { b = 1U << (bits - 1), m = (1U << bits) - 1 };
|
||||
return ((x & m) ^ b) - b;
|
||||
}
|
||||
|
||||
/*****
|
||||
* endian wrappers
|
||||
*****/
|
||||
|
||||
#ifndef ARCH_MSB
|
||||
//little-endian: uint8[] { 0x01, 0x02, 0x03, 0x04 } = 0x04030201
|
||||
#define order_lsb2(a,b) a,b
|
||||
#define order_lsb3(a,b,c) a,b,c
|
||||
#define order_lsb4(a,b,c,d) a,b,c,d
|
||||
#define order_lsb5(a,b,c,d,e) a,b,c,d,e
|
||||
#define order_lsb6(a,b,c,d,e,f) a,b,c,d,e,f
|
||||
#define order_lsb7(a,b,c,d,e,f,g) a,b,c,d,e,f,g
|
||||
#define order_lsb8(a,b,c,d,e,f,g,h) a,b,c,d,e,f,g,h
|
||||
#define order_msb2(a,b) b,a
|
||||
#define order_msb3(a,b,c) c,b,a
|
||||
#define order_msb4(a,b,c,d) d,c,b,a
|
||||
#define order_msb5(a,b,c,d,e) e,d,c,b,a
|
||||
#define order_msb6(a,b,c,d,e,f) f,e,d,c,b,a
|
||||
#define order_msb7(a,b,c,d,e,f,g) g,f,e,d,c,b,a
|
||||
#define order_msb8(a,b,c,d,e,f,g,h) h,g,f,e,d,c,b,a
|
||||
#else
|
||||
//big-endian: uint8[] { 0x01, 0x02, 0x03, 0x04 } = 0x01020304
|
||||
#define order_lsb2(a,b) b,a
|
||||
#define order_lsb3(a,b,c) c,b,a
|
||||
#define order_lsb4(a,b,c,d) d,c,b,a
|
||||
#define order_lsb5(a,b,c,d,e) e,d,c,b,a
|
||||
#define order_lsb6(a,b,c,d,e,f) f,e,d,c,b,a
|
||||
#define order_lsb7(a,b,c,d,e,f,g) g,f,e,d,c,b,a
|
||||
#define order_lsb8(a,b,c,d,e,f,g,h) h,g,f,e,d,c,b,a
|
||||
#define order_msb2(a,b) a,b
|
||||
#define order_msb3(a,b,c) a,b,c
|
||||
#define order_msb4(a,b,c,d) a,b,c,d
|
||||
#define order_msb5(a,b,c,d,e) a,b,c,d,e
|
||||
#define order_msb6(a,b,c,d,e,f) a,b,c,d,e,f
|
||||
#define order_msb7(a,b,c,d,e,f,g) a,b,c,d,e,f,g
|
||||
#define order_msb8(a,b,c,d,e,f,g,h) a,b,c,d,e,f,g,h
|
||||
#ifndef ARCH_MSB
|
||||
//little-endian: uint8[] { 0x01, 0x02, 0x03, 0x04 } == 0x04030201
|
||||
#define order_lsb2(a,b) a,b
|
||||
#define order_lsb3(a,b,c) a,b,c
|
||||
#define order_lsb4(a,b,c,d) a,b,c,d
|
||||
#define order_lsb5(a,b,c,d,e) a,b,c,d,e
|
||||
#define order_lsb6(a,b,c,d,e,f) a,b,c,d,e,f
|
||||
#define order_lsb7(a,b,c,d,e,f,g) a,b,c,d,e,f,g
|
||||
#define order_lsb8(a,b,c,d,e,f,g,h) a,b,c,d,e,f,g,h
|
||||
#define order_msb2(a,b) b,a
|
||||
#define order_msb3(a,b,c) c,b,a
|
||||
#define order_msb4(a,b,c,d) d,c,b,a
|
||||
#define order_msb5(a,b,c,d,e) e,d,c,b,a
|
||||
#define order_msb6(a,b,c,d,e,f) f,e,d,c,b,a
|
||||
#define order_msb7(a,b,c,d,e,f,g) g,f,e,d,c,b,a
|
||||
#define order_msb8(a,b,c,d,e,f,g,h) h,g,f,e,d,c,b,a
|
||||
#else
|
||||
//big-endian: uint8[] { 0x01, 0x02, 0x03, 0x04 } == 0x01020304
|
||||
#define order_lsb2(a,b) b,a
|
||||
#define order_lsb3(a,b,c) c,b,a
|
||||
#define order_lsb4(a,b,c,d) d,c,b,a
|
||||
#define order_lsb5(a,b,c,d,e) e,d,c,b,a
|
||||
#define order_lsb6(a,b,c,d,e,f) f,e,d,c,b,a
|
||||
#define order_lsb7(a,b,c,d,e,f,g) g,f,e,d,c,b,a
|
||||
#define order_lsb8(a,b,c,d,e,f,g,h) h,g,f,e,d,c,b,a
|
||||
#define order_msb2(a,b) a,b
|
||||
#define order_msb3(a,b,c) a,b,c
|
||||
#define order_msb4(a,b,c,d) a,b,c,d
|
||||
#define order_msb5(a,b,c,d,e) a,b,c,d,e
|
||||
#define order_msb6(a,b,c,d,e,f) a,b,c,d,e,f
|
||||
#define order_msb7(a,b,c,d,e,f,g) a,b,c,d,e,f,g
|
||||
#define order_msb8(a,b,c,d,e,f,g,h) a,b,c,d,e,f,g,h
|
||||
#endif
|
||||
|
||||
/*****
|
||||
* libc extensions
|
||||
*****/
|
||||
|
||||
//static uint random() {
|
||||
//static uint n = 0;
|
||||
// return n = (n >> 1) ^ (((n & 1) - 1) & 0xedb88320);
|
||||
//}
|
||||
|
||||
//pseudo-random number generator
|
||||
static uint prng() {
|
||||
static uint n = 0;
|
||||
return n = (n >> 1) ^ (((n & 1) - 1) & 0xedb88320);
|
||||
}
|
||||
|
||||
static uint64 fget(FILE *fp, uint length = 1) {
|
||||
uint64 data = 0;
|
||||
@@ -263,7 +228,6 @@ static int fresize(FILE *fp, long size) {
|
||||
|
||||
/*****
|
||||
* crc32 calculation
|
||||
* TODO: create libhash and move this code there
|
||||
*****/
|
||||
|
||||
const uint32 crc32_table[256] = {
|
||||
@@ -324,4 +288,4 @@ uint32 crc32 = ~0;
|
||||
return ~crc32;
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif //ifndef BBASE_H
|
||||
@@ -0,0 +1,269 @@
|
||||
#include <hiro.h>
|
||||
using namespace nall;
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include <hiro_win/hiro.cpp>
|
||||
#else
|
||||
#include <hiro_gtk/hiro.cpp>
|
||||
#endif
|
||||
|
||||
namespace libhiro {
|
||||
|
||||
/* Hiro (singleton) */
|
||||
|
||||
void Hiro::init() { p.init(); }
|
||||
void Hiro::term() { p.term(); }
|
||||
bool Hiro::run() { return p.run(); }
|
||||
bool Hiro::pending() { return p.pending(); }
|
||||
bool Hiro::file_load(Window *focus, char *filename, const char *filter, const char *path) { return p.file_load(focus, filename, filter, path); }
|
||||
bool Hiro::file_save(Window *focus, char *filename, const char *filter, const char *path) { return p.file_save(focus, filename, filter, path); }
|
||||
uint Hiro::screen_width() { return p.screen_width(); }
|
||||
uint Hiro::screen_height() { return p.screen_height(); }
|
||||
Hiro& Hiro::handle() { static Hiro hiro; return hiro; }
|
||||
Hiro::Hiro() : p(*new pHiro(*this)) {}
|
||||
Hiro::~Hiro() { delete &p; }
|
||||
Hiro& hiro() { return Hiro::handle(); }
|
||||
|
||||
/* Widget */
|
||||
|
||||
void Widget::show(bool state) { p.show(state); }
|
||||
void Widget::hide() { p.hide(); }
|
||||
bool Widget::visible() { return p.visible(); }
|
||||
uintptr_t Widget::handle() { return p.handle(); }
|
||||
Widget::Widget() : p(*new pWidget(*this)) { type = WidgetType; }
|
||||
Widget::Widget(pWidget &p_) : p(p_) { type = WidgetType; }
|
||||
Widget::~Widget() { delete &p; }
|
||||
|
||||
/* Widget -> Window */
|
||||
|
||||
void Window::create(uint style, uint width, uint height, const char *text) { p.create(style, width, height, text); }
|
||||
void Window::close() { p.close(); }
|
||||
void Window::move(uint x, uint y) { p.move(x, y); }
|
||||
void Window::resize(uint width, uint height) { p.resize(width, height); }
|
||||
void Window::focus() { p.focus(); }
|
||||
bool Window::focused() { return p.focused(); }
|
||||
void Window::fullscreen() { p.fullscreen(); }
|
||||
void Window::unfullscreen() { p.unfullscreen(); }
|
||||
uint Window::get_width() { return p.get_width(); }
|
||||
uint Window::get_height() { return p.get_height(); }
|
||||
void Window::set_background_color(uint8_t r, uint8_t g, uint8_t b) { p.set_background_color(r, g, b); }
|
||||
void Window::set_text(const char *text) { p.set_text(text); }
|
||||
void Window::attach(Window &window, uint x, uint y) { p.attach(window, x, y); }
|
||||
void Window::attach(MenuGroup &menugroup) { p.attach(menugroup); }
|
||||
void Window::attach(FormControl &formcontrol, uint x, uint y) { p.attach(formcontrol, x, y); }
|
||||
void Window::move(Window &window, uint x, uint y) { p.move(window, x, y); }
|
||||
void Window::move(FormControl &formcontrol, uint x, uint y) { p.move(formcontrol, x, y); }
|
||||
|
||||
void Window::Menubar::show(bool state) { p.menu.show(state); }
|
||||
void Window::Menubar::hide() { p.menu.hide(); }
|
||||
bool Window::Menubar::visible() { return p.menu.visible(); }
|
||||
Window::Menubar::Menubar(pWindow &p_) : p(p_) {}
|
||||
|
||||
void Window::Statusbar::set_text(const char *text) { p.status.set_text(text); }
|
||||
void Window::Statusbar::show(bool state) { p.status.show(state); }
|
||||
void Window::Statusbar::hide() { p.status.hide(); }
|
||||
bool Window::Statusbar::visible() { return p.status.visible(); }
|
||||
Window::Statusbar::Statusbar(pWindow &p_) : p(p_) {}
|
||||
|
||||
Window::Window() :
|
||||
base_from_member<pWindow&>(*new pWindow(*this)),
|
||||
Widget(base_from_member<pWindow&>::value),
|
||||
p(base_from_member<pWindow&>::value),
|
||||
menu(base_from_member<pWindow&>::value),
|
||||
status(base_from_member<pWindow&>::value) { type = WindowType; }
|
||||
|
||||
/* Widget -> MenuControl */
|
||||
|
||||
void MenuControl::enable(bool state) { p.enable(state); }
|
||||
void MenuControl::disable() { p.disable(); }
|
||||
bool MenuControl::enabled() { return p.enabled(); }
|
||||
MenuControl::MenuControl() :
|
||||
base_from_member<pMenuControl&>(*new pMenuControl(*this)),
|
||||
Widget(base_from_member<pMenuControl&>::value),
|
||||
p(base_from_member<pMenuControl&>::value) { type = MenuControlType; }
|
||||
MenuControl::MenuControl(pMenuControl &p_) :
|
||||
base_from_member<pMenuControl&>(p_),
|
||||
Widget(base_from_member<pMenuControl&>::value),
|
||||
p(base_from_member<pMenuControl&>::value) { type = MenuControlType; }
|
||||
|
||||
/* Widget -> MenuControl -> MenuGroup */
|
||||
|
||||
MenuGroup& MenuGroup::create(const char *text) { p.create(text); return *this; }
|
||||
void MenuGroup::attach(MenuControl &menucontrol) { p.attach(menucontrol); }
|
||||
MenuGroup::MenuGroup() :
|
||||
base_from_member<pMenuGroup&>(*new pMenuGroup(*this)),
|
||||
MenuControl(base_from_member<pMenuGroup&>::value),
|
||||
p(base_from_member<pMenuGroup&>::value) { type = MenuGroupType; }
|
||||
|
||||
/* Widget -> MenuControl -> MenuItem */
|
||||
|
||||
MenuItem& MenuItem::create(const char *text) { p.create(text); return *this; }
|
||||
MenuItem::MenuItem() :
|
||||
base_from_member<pMenuItem&>(*new pMenuItem(*this)),
|
||||
MenuControl(base_from_member<pMenuItem&>::value),
|
||||
p(base_from_member<pMenuItem&>::value) { type = MenuItemType; }
|
||||
|
||||
/* Widget -> MenuControl -> MenuCheckItem */
|
||||
|
||||
MenuCheckItem& MenuCheckItem::create(const char *text) { p.create(text); return *this; }
|
||||
void MenuCheckItem::check(bool state) { state ? p.check() : p.uncheck(); }
|
||||
void MenuCheckItem::uncheck() { p.uncheck(); }
|
||||
bool MenuCheckItem::checked() { return p.checked(); }
|
||||
MenuCheckItem::MenuCheckItem() :
|
||||
base_from_member<pMenuCheckItem&>(*new pMenuCheckItem(*this)),
|
||||
MenuControl(base_from_member<pMenuCheckItem&>::value),
|
||||
p(base_from_member<pMenuCheckItem&>::value) { type = MenuCheckItemType; }
|
||||
|
||||
/* Widget -> MenuControl -> MenuRadioItem */
|
||||
|
||||
MenuRadioItem& MenuRadioItem::create(MenuRadioItemGroup &group, const char *text) { p.create(group, text); return *this; }
|
||||
void MenuRadioItem::check() { p.check(); }
|
||||
bool MenuRadioItem::checked() { return p.checked(); }
|
||||
MenuRadioItem::MenuRadioItem() :
|
||||
base_from_member<pMenuRadioItem&>(*new pMenuRadioItem(*this)),
|
||||
MenuControl(base_from_member<pMenuRadioItem&>::value),
|
||||
p(base_from_member<pMenuRadioItem&>::value) { type = MenuRadioItemType; }
|
||||
|
||||
/* Widget -> MenuControl -> MenuSeparator */
|
||||
|
||||
MenuSeparator& MenuSeparator::create() { p.create(); return *this; }
|
||||
MenuSeparator::MenuSeparator() :
|
||||
base_from_member<pMenuSeparator&>(*new pMenuSeparator(*this)),
|
||||
MenuControl(base_from_member<pMenuSeparator&>::value),
|
||||
p(base_from_member<pMenuSeparator&>::value) { type = MenuSeparatorType; }
|
||||
|
||||
/* Widget -> FormControl */
|
||||
|
||||
void FormControl::resize(uint width, uint height) { p.resize(width, height); }
|
||||
void FormControl::focus() { p.focus(); }
|
||||
bool FormControl::focused() { return p.focused(); }
|
||||
void FormControl::enable(bool state) { p.enable(state); }
|
||||
void FormControl::disable() { p.disable(); }
|
||||
bool FormControl::enabled() { return p.enabled(); }
|
||||
FormControl::FormControl() :
|
||||
base_from_member<pFormControl&>(*new pFormControl(*this)),
|
||||
Widget(base_from_member<pFormControl&>::value),
|
||||
p(base_from_member<pFormControl&>::value) { type = FormControlType; }
|
||||
FormControl::FormControl(pFormControl &p_) :
|
||||
base_from_member<pFormControl&>(p_),
|
||||
Widget(base_from_member<pFormControl&>::value),
|
||||
p(base_from_member<pFormControl&>::value) { type = FormControlType; }
|
||||
|
||||
/* Widget -> FormControl -> Frame */
|
||||
|
||||
void Frame::create(uint style, uint width, uint height, const char *text) { p.create(style, width, height, text); }
|
||||
void Frame::set_text(const char *text) { p.set_text(text); }
|
||||
Frame::Frame() :
|
||||
base_from_member<pFrame&>(*new pFrame(*this)),
|
||||
FormControl(base_from_member<pFrame&>::value),
|
||||
p(base_from_member<pFrame&>::value) { type = FrameType; }
|
||||
|
||||
/* Widget -> FormControl -> Canvas */
|
||||
|
||||
void Canvas::create(uint style, uint width, uint height) { p.create(style, width, height); }
|
||||
void Canvas::redraw() { p.redraw(); }
|
||||
uint32_t* Canvas::buffer() { return p.buffer(); }
|
||||
Canvas::Canvas() :
|
||||
base_from_member<pCanvas&>(*new pCanvas(*this)),
|
||||
FormControl(base_from_member<pCanvas&>::value),
|
||||
p(base_from_member<pCanvas&>::value) { type = CanvasType; }
|
||||
|
||||
/* Widget -> FormControl -> Label */
|
||||
|
||||
void Label::create(uint style, uint width, uint height, const char *text) { p.create(style, width, height, text); }
|
||||
void Label::set_text(const char *text) { p.set_text(text); }
|
||||
Label::Label() :
|
||||
base_from_member<pLabel&>(*new pLabel(*this)),
|
||||
FormControl(base_from_member<pLabel&>::value),
|
||||
p(base_from_member<pLabel&>::value) { type = LabelType; }
|
||||
|
||||
/* Widget -> FormControl -> Button */
|
||||
|
||||
void Button::create(uint style, uint width, uint height, const char *text) { p.create(style, width, height, text); }
|
||||
void Button::set_text(const char *text) { p.set_text(text); }
|
||||
Button::Button() :
|
||||
base_from_member<pButton&>(*new pButton(*this)),
|
||||
FormControl(base_from_member<pButton&>::value),
|
||||
p(base_from_member<pButton&>::value) { type = ButtonType; }
|
||||
|
||||
/* Widget -> FormControl -> Checkbox */
|
||||
|
||||
void Checkbox::create(uint style, uint width, uint height, const char *text) { p.create(style, width, height, text); }
|
||||
void Checkbox::set_text(const char *text) { p.set_text(text); }
|
||||
void Checkbox::check(bool state) { state ? p.check() : p.uncheck(); }
|
||||
void Checkbox::uncheck() { p.uncheck(); }
|
||||
bool Checkbox::checked() { return p.checked(); }
|
||||
Checkbox::Checkbox() :
|
||||
base_from_member<pCheckbox&>(*new pCheckbox(*this)),
|
||||
FormControl(base_from_member<pCheckbox&>::value),
|
||||
p(base_from_member<pCheckbox&>::value) { type = CheckboxType; }
|
||||
|
||||
/* Widget -> FormControl -> Radiobox */
|
||||
|
||||
void Radiobox::create(RadioboxGroup &group, uint style, uint width, uint height, const char *text) { p.create(group, style, width, height, text); }
|
||||
void Radiobox::set_text(const char *text) { p.set_text(text); }
|
||||
void Radiobox::check() { p.check(); }
|
||||
bool Radiobox::checked() { return p.checked(); }
|
||||
Radiobox::Radiobox() :
|
||||
base_from_member<pRadiobox&>(*new pRadiobox(*this)),
|
||||
FormControl(base_from_member<pRadiobox&>::value),
|
||||
p(base_from_member<pRadiobox&>::value) { type = RadioboxType; }
|
||||
|
||||
/* Widget -> FormControl -> Editbox */
|
||||
|
||||
void Editbox::create(uint style, uint width, uint height, const char *text) { p.create(style, width, height, text); }
|
||||
uint Editbox::get_text(char *text, uint length) { return p.get_text(text, length); }
|
||||
void Editbox::set_text(const char *text) { p.set_text(text); }
|
||||
Editbox::Editbox() :
|
||||
base_from_member<pEditbox&>(*new pEditbox(*this)),
|
||||
FormControl(base_from_member<pEditbox&>::value),
|
||||
p(base_from_member<pEditbox&>::value) { type = EditboxType; }
|
||||
|
||||
/* Widget -> FormControl -> Listbox */
|
||||
|
||||
void Listbox::create(uint style, uint width, uint height, const char *columns, const char *text) { p.create(style, width, height, columns, text); }
|
||||
void Listbox::autosize_columns() { p.autosize_columns(); }
|
||||
void Listbox::set_column_width(uint column, uint width) { p.set_column_width(column, width); }
|
||||
void Listbox::add_item(const char *text) { p.add_item(text); }
|
||||
void Listbox::set_item(uint index, const char *text) { p.set_item(index, text); }
|
||||
int Listbox::get_selection() { return p.get_selection(); }
|
||||
void Listbox::set_selection(int index) { p.set_selection(index); }
|
||||
void Listbox::reset() { p.reset(); }
|
||||
Listbox::Listbox() :
|
||||
base_from_member<pListbox&>(*new pListbox(*this)),
|
||||
FormControl(base_from_member<pListbox&>::value),
|
||||
p(base_from_member<pListbox&>::value) { type = ListboxType; }
|
||||
|
||||
/* Widget -> FormControl -> Combobox */
|
||||
|
||||
void Combobox::create(uint style, uint width, uint height, const char *text) { p.create(style, width, height, text); }
|
||||
void Combobox::add_item(const char *text) { p.add_item(text); }
|
||||
int Combobox::get_selection() { return p.get_selection(); }
|
||||
void Combobox::set_selection(int index) { p.set_selection(index); }
|
||||
void Combobox::reset() { p.reset(); }
|
||||
Combobox::Combobox() :
|
||||
base_from_member<pCombobox&>(*new pCombobox(*this)),
|
||||
FormControl(base_from_member<pCombobox&>::value),
|
||||
p(base_from_member<pCombobox&>::value) { type = ComboboxType; }
|
||||
|
||||
/* Widget -> FormControl -> Progressbar */
|
||||
|
||||
void Progressbar::create(uint style, uint width, uint height) { p.create(style, width, height); }
|
||||
uint Progressbar::get_progress() { return p.get_progress(); }
|
||||
void Progressbar::set_progress(uint progress) { p.set_progress(progress); }
|
||||
Progressbar::Progressbar() :
|
||||
base_from_member<pProgressbar&>(*new pProgressbar(*this)),
|
||||
FormControl(base_from_member<pProgressbar&>::value),
|
||||
p(base_from_member<pProgressbar&>::value) { type = ProgressbarType; }
|
||||
|
||||
/* Widget -> FormControl -> Slider */
|
||||
|
||||
void Slider::create(uint style, uint width, uint height, uint length) { p.create(style, width, height, length); }
|
||||
uint Slider::get_position() { return p.get_position(); }
|
||||
void Slider::set_position(uint position) { p.set_position(position); }
|
||||
Slider::Slider() :
|
||||
base_from_member<pSlider&>(*new pSlider(*this)),
|
||||
FormControl(base_from_member<pSlider&>::value),
|
||||
p(base_from_member<pSlider&>::value) { type = SliderType; }
|
||||
|
||||
} //namespace libhiro
|
||||
+526
@@ -0,0 +1,526 @@
|
||||
/*
|
||||
hiro
|
||||
version: 0.001 (2008-02-03)
|
||||
author: byuu
|
||||
license: public domain
|
||||
*/
|
||||
|
||||
#ifndef HIRO_H
|
||||
#define HIRO_H
|
||||
|
||||
#include <nall/array.hpp>
|
||||
#include <nall/function.hpp>
|
||||
#include <nall/input.hpp>
|
||||
#include <nall/stdint.hpp>
|
||||
#include <nall/string.hpp>
|
||||
#include <nall/utility.hpp>
|
||||
typedef unsigned int uint;
|
||||
|
||||
namespace libhiro {
|
||||
|
||||
class pHiro;
|
||||
class pWidget;
|
||||
class pWindow;
|
||||
class pMenuControl;
|
||||
class pMenuGroup;
|
||||
class pMenuItem;
|
||||
class pMenuCheckItem;
|
||||
class pMenuRadioItem;
|
||||
class pMenuSeparator;
|
||||
class pFormControl;
|
||||
class pFrame;
|
||||
class pCanvas;
|
||||
class pLabel;
|
||||
class pButton;
|
||||
class pCheckbox;
|
||||
class pRadiobox;
|
||||
class pEditbox;
|
||||
class pListbox;
|
||||
class pCombobox;
|
||||
class pProgressbar;
|
||||
class pSlider;
|
||||
|
||||
#define pFriends \
|
||||
friend class pHiro; \
|
||||
friend class pWidget; \
|
||||
friend class pWindow; \
|
||||
friend class pMenuControl; \
|
||||
friend class pMenuGroup; \
|
||||
friend class pMenuItem; \
|
||||
friend class pMenuCheckItem; \
|
||||
friend class pMenuRadioItem; \
|
||||
friend class pMenuSeparator; \
|
||||
friend class pFormControl; \
|
||||
friend class pFrame; \
|
||||
friend class pCanvas; \
|
||||
friend class pLabel; \
|
||||
friend class pButton; \
|
||||
friend class pCheckbox; \
|
||||
friend class pRadiobox; \
|
||||
friend class pEditbox; \
|
||||
friend class pListbox; \
|
||||
friend class pCombobox; \
|
||||
friend class pProgressbar; \
|
||||
friend class pSlider
|
||||
|
||||
class Hiro;
|
||||
class Widget;
|
||||
class Window;
|
||||
class MenuControl;
|
||||
class MenuGroup;
|
||||
class MenuItem;
|
||||
class MenuCheckItem;
|
||||
class MenuRadioItem;
|
||||
class MenuSeparator;
|
||||
class FormControl;
|
||||
class Frame;
|
||||
class Canvas;
|
||||
class Label;
|
||||
class Button;
|
||||
class Checkbox;
|
||||
class Radiobox;
|
||||
class Editbox;
|
||||
class Listbox;
|
||||
class Combobox;
|
||||
class Progressbar;
|
||||
class Slider;
|
||||
|
||||
typedef nall::array<MenuRadioItem*> MenuRadioItemGroup;
|
||||
typedef nall::array<Radiobox*> RadioboxGroup;
|
||||
|
||||
struct Event {
|
||||
enum Type {
|
||||
Close,
|
||||
Block,
|
||||
KeyDown,
|
||||
KeyUp,
|
||||
Change,
|
||||
Tick,
|
||||
Activate,
|
||||
} type;
|
||||
uintptr_t param;
|
||||
Widget *widget;
|
||||
|
||||
Event(Type type_, uintptr_t param_ = 0, Widget *widget_ = 0) :
|
||||
type(type_), param(param_), widget(widget_) {}
|
||||
};
|
||||
|
||||
class Hiro : nall::noncopyable {
|
||||
public:
|
||||
void init();
|
||||
void term();
|
||||
bool run();
|
||||
bool pending();
|
||||
|
||||
bool file_load(Window *focus, char *filename, const char *filter, const char *path);
|
||||
bool file_save(Window *focus, char *filename, const char *filter, const char *path);
|
||||
|
||||
uint screen_width();
|
||||
uint screen_height();
|
||||
|
||||
static Hiro& handle();
|
||||
Hiro();
|
||||
~Hiro();
|
||||
|
||||
private:
|
||||
pFriends;
|
||||
pHiro &p;
|
||||
};
|
||||
|
||||
Hiro& hiro();
|
||||
|
||||
class Widget : nall::noncopyable {
|
||||
public:
|
||||
enum Type {
|
||||
WidgetType,
|
||||
WindowType,
|
||||
MenuControlType,
|
||||
MenuGroupType,
|
||||
MenuItemType,
|
||||
MenuCheckItemType,
|
||||
MenuRadioItemType,
|
||||
MenuSeparatorType,
|
||||
FormControlType,
|
||||
FrameType,
|
||||
CanvasType,
|
||||
LabelType,
|
||||
ButtonType,
|
||||
CheckboxType,
|
||||
RadioboxType,
|
||||
EditboxType,
|
||||
ListboxType,
|
||||
ComboboxType,
|
||||
ProgressbarType,
|
||||
SliderType,
|
||||
} type;
|
||||
|
||||
void show(bool = true);
|
||||
void hide();
|
||||
bool visible();
|
||||
|
||||
uintptr_t handle();
|
||||
|
||||
Widget();
|
||||
~Widget();
|
||||
|
||||
protected:
|
||||
Widget(pWidget&);
|
||||
|
||||
private:
|
||||
pFriends;
|
||||
pWidget &p;
|
||||
};
|
||||
|
||||
class Window : private nall::base_from_member<pWindow&>, public Widget {
|
||||
public:
|
||||
enum Style {
|
||||
AutoCenter = 1 << 1,
|
||||
};
|
||||
|
||||
void create(uint style, uint width, uint height, const char *text = "");
|
||||
void close();
|
||||
void move(uint x, uint y);
|
||||
void resize(uint width, uint height);
|
||||
void focus();
|
||||
bool focused();
|
||||
void fullscreen();
|
||||
void unfullscreen();
|
||||
uint get_width();
|
||||
uint get_height();
|
||||
void set_background_color(uint8_t r, uint8_t g, uint8_t b);
|
||||
void set_status_text(const char *text = "");
|
||||
void set_text(const char *text = "");
|
||||
void attach(Window &window, uint x, uint y);
|
||||
void attach(MenuGroup &menugroup);
|
||||
void attach(FormControl &formcontrol, uint x, uint y);
|
||||
void move(Window &window, uint x, uint y);
|
||||
void move(FormControl &formcontrol, uint x, uint y);
|
||||
|
||||
class Menubar {
|
||||
public:
|
||||
void show(bool = true);
|
||||
void hide();
|
||||
bool visible();
|
||||
|
||||
pWindow &p;
|
||||
Menubar(pWindow&);
|
||||
} menu;
|
||||
|
||||
class Statusbar {
|
||||
public:
|
||||
void set_text(const char *text = "");
|
||||
void show(bool = true);
|
||||
void hide();
|
||||
bool visible();
|
||||
|
||||
pWindow &p;
|
||||
Statusbar(pWindow&);
|
||||
} status;
|
||||
|
||||
nall::function<uintptr_t (Event)> on_close;
|
||||
nall::function<uintptr_t (Event)> on_block;
|
||||
nall::function<uintptr_t (Event)> on_keydown;
|
||||
nall::function<uintptr_t (Event)> on_keyup;
|
||||
|
||||
Window();
|
||||
|
||||
private:
|
||||
pFriends;
|
||||
pWindow &p;
|
||||
};
|
||||
|
||||
class MenuControl : public nall::base_from_member<pMenuControl&>, public Widget {
|
||||
public:
|
||||
void enable(bool = true);
|
||||
void disable();
|
||||
bool enabled();
|
||||
|
||||
MenuControl();
|
||||
|
||||
protected:
|
||||
MenuControl(pMenuControl&);
|
||||
|
||||
private:
|
||||
pFriends;
|
||||
pMenuControl &p;
|
||||
};
|
||||
|
||||
class MenuGroup : public nall::base_from_member<pMenuGroup&>, public MenuControl {
|
||||
public:
|
||||
MenuGroup& create(const char *text);
|
||||
void attach(MenuControl &menucontrol);
|
||||
MenuGroup();
|
||||
|
||||
private:
|
||||
pFriends;
|
||||
pMenuGroup &p;
|
||||
};
|
||||
|
||||
class MenuItem : public nall::base_from_member<pMenuItem&>, public MenuControl {
|
||||
public:
|
||||
MenuItem& create(const char *text);
|
||||
MenuItem();
|
||||
|
||||
nall::function<uintptr_t (Event)> on_tick;
|
||||
|
||||
private:
|
||||
pFriends;
|
||||
pMenuItem &p;
|
||||
};
|
||||
|
||||
class MenuCheckItem : public nall::base_from_member<pMenuCheckItem&>, public MenuControl {
|
||||
public:
|
||||
MenuCheckItem& create(const char *text);
|
||||
void check(bool = true);
|
||||
void uncheck();
|
||||
bool checked();
|
||||
MenuCheckItem();
|
||||
|
||||
nall::function<uintptr_t (Event)> on_tick;
|
||||
|
||||
private:
|
||||
pFriends;
|
||||
pMenuCheckItem &p;
|
||||
};
|
||||
|
||||
class MenuRadioItem : public nall::base_from_member<pMenuRadioItem&>, public MenuControl {
|
||||
public:
|
||||
MenuRadioItem& create(MenuRadioItemGroup &group, const char *text);
|
||||
void check();
|
||||
bool checked();
|
||||
MenuRadioItem();
|
||||
|
||||
nall::function<uintptr_t (Event)> on_tick;
|
||||
|
||||
private:
|
||||
pFriends;
|
||||
pMenuRadioItem &p;
|
||||
};
|
||||
|
||||
class MenuSeparator : public nall::base_from_member<pMenuSeparator&>, public MenuControl {
|
||||
public:
|
||||
MenuSeparator& create();
|
||||
MenuSeparator();
|
||||
|
||||
private:
|
||||
pFriends;
|
||||
pMenuSeparator &p;
|
||||
};
|
||||
|
||||
class FormControl : private nall::base_from_member<pFormControl&>, public Widget {
|
||||
public:
|
||||
void resize(uint width, uint height);
|
||||
void focus();
|
||||
bool focused();
|
||||
void enable(bool = true);
|
||||
void disable();
|
||||
bool enabled();
|
||||
|
||||
FormControl();
|
||||
|
||||
protected:
|
||||
FormControl(pFormControl&);
|
||||
|
||||
private:
|
||||
pFriends;
|
||||
pFormControl &p;
|
||||
};
|
||||
|
||||
class Frame : private nall::base_from_member<pFrame&>, public FormControl {
|
||||
public:
|
||||
void create(uint style, uint width, uint height, const char *text = "");
|
||||
void set_text(const char *text = "");
|
||||
|
||||
Frame();
|
||||
|
||||
private:
|
||||
pFriends;
|
||||
pFrame &p;
|
||||
};
|
||||
|
||||
class Canvas : private nall::base_from_member<pCanvas&>, public FormControl {
|
||||
public:
|
||||
void create(uint style, uint width, uint height);
|
||||
void redraw();
|
||||
uint32_t* buffer();
|
||||
|
||||
Canvas();
|
||||
|
||||
private:
|
||||
pFriends;
|
||||
pCanvas &p;
|
||||
};
|
||||
|
||||
class Label : private nall::base_from_member<pLabel&>, public FormControl {
|
||||
public:
|
||||
void create(uint style, uint width, uint height, const char *text = "");
|
||||
void set_text(const char *text = "");
|
||||
|
||||
Label();
|
||||
|
||||
private:
|
||||
pFriends;
|
||||
pLabel &p;
|
||||
};
|
||||
|
||||
class Button : private nall::base_from_member<pButton&>, public FormControl {
|
||||
public:
|
||||
void create(uint style, uint width, uint height, const char *text = "");
|
||||
void set_text(const char *text = "");
|
||||
|
||||
nall::function<uintptr_t (Event)> on_tick;
|
||||
|
||||
Button();
|
||||
|
||||
private:
|
||||
pFriends;
|
||||
pButton &p;
|
||||
};
|
||||
|
||||
class Checkbox : private nall::base_from_member<pCheckbox&>, public FormControl {
|
||||
public:
|
||||
void create(uint style, uint width, uint height, const char *text = "");
|
||||
void set_text(const char *text = "");
|
||||
void check(bool = true);
|
||||
void uncheck();
|
||||
bool checked();
|
||||
|
||||
nall::function<uintptr_t (Event)> on_tick;
|
||||
|
||||
Checkbox();
|
||||
|
||||
private:
|
||||
pFriends;
|
||||
pCheckbox &p;
|
||||
};
|
||||
|
||||
class Radiobox : private nall::base_from_member<pRadiobox&>, public FormControl {
|
||||
public:
|
||||
void create(RadioboxGroup &group, uint style, uint width, uint height, const char *text = "");
|
||||
void set_text(const char *text = "");
|
||||
void check();
|
||||
bool checked();
|
||||
|
||||
nall::function<uintptr_t (Event)> on_tick;
|
||||
|
||||
Radiobox();
|
||||
|
||||
private:
|
||||
pFriends;
|
||||
pRadiobox &p;
|
||||
};
|
||||
|
||||
class Editbox : private nall::base_from_member<pEditbox&>, public FormControl {
|
||||
public:
|
||||
enum Style {
|
||||
Multiline = 1 << 1,
|
||||
Readonly = 1 << 2,
|
||||
|
||||
HorizontalScrollAuto = 0,
|
||||
HorizontalScrollAlways = 1 << 3,
|
||||
HorizontalScrollNever = 1 << 4,
|
||||
|
||||
VerticalScrollAuto = 0,
|
||||
VerticalScrollAlways = 1 << 5,
|
||||
VerticalScrollNever = 1 << 6,
|
||||
};
|
||||
|
||||
void create(uint style, uint width, uint height, const char *text = "");
|
||||
uint get_text(char *text, uint length = -1U);
|
||||
void set_text(const char *text = "");
|
||||
|
||||
Editbox();
|
||||
|
||||
private:
|
||||
pFriends;
|
||||
pEditbox &p;
|
||||
};
|
||||
|
||||
class Listbox : private nall::base_from_member<pListbox&>, public FormControl {
|
||||
public:
|
||||
enum Style {
|
||||
Header = 1 << 1,
|
||||
|
||||
HorizontalScrollAuto = 0,
|
||||
HorizontalScrollAlways = 1 << 2,
|
||||
HorizontalScrollNever = 1 << 3,
|
||||
|
||||
VerticalScrollAuto = 0,
|
||||
VerticalScrollAlways = 1 << 4,
|
||||
VerticalScrollNever = 1 << 5,
|
||||
};
|
||||
|
||||
void create(uint style, uint width, uint height, const char *columns = "", const char *text = "");
|
||||
void autosize_columns();
|
||||
void set_column_width(uint column, uint width);
|
||||
void add_item(const char *text);
|
||||
void set_item(uint index, const char *text);
|
||||
int get_selection();
|
||||
void set_selection(int index);
|
||||
void reset();
|
||||
|
||||
nall::function<uintptr_t (Event)> on_change;
|
||||
nall::function<uintptr_t (Event)> on_activate;
|
||||
|
||||
Listbox();
|
||||
|
||||
private:
|
||||
pFriends;
|
||||
pListbox &p;
|
||||
};
|
||||
|
||||
class Combobox : private nall::base_from_member<pCombobox&>, public FormControl {
|
||||
public:
|
||||
void create(uint style, uint width, uint height, const char *text = "");
|
||||
void add_item(const char *text);
|
||||
int get_selection();
|
||||
void set_selection(int index);
|
||||
void reset();
|
||||
|
||||
nall::function<uintptr_t (Event)> on_change;
|
||||
|
||||
Combobox();
|
||||
|
||||
private:
|
||||
pFriends;
|
||||
pCombobox &p;
|
||||
};
|
||||
|
||||
class Progressbar : private nall::base_from_member<pProgressbar&>, public FormControl {
|
||||
public:
|
||||
void create(uint style, uint width, uint height);
|
||||
uint get_progress();
|
||||
void set_progress(uint progress);
|
||||
|
||||
Progressbar();
|
||||
|
||||
private:
|
||||
pFriends;
|
||||
pProgressbar &p;
|
||||
};
|
||||
|
||||
class Slider : private nall::base_from_member<pSlider&>, public FormControl {
|
||||
public:
|
||||
enum Style {
|
||||
Horizontal = 0,
|
||||
Vertical = 1 << 1,
|
||||
};
|
||||
|
||||
void create(uint style, uint width, uint height, uint length);
|
||||
uint get_position();
|
||||
void set_position(uint position);
|
||||
|
||||
nall::function<uintptr_t (Event)> on_change;
|
||||
|
||||
Slider();
|
||||
|
||||
private:
|
||||
pFriends;
|
||||
pSlider &p;
|
||||
};
|
||||
|
||||
#undef pFriends
|
||||
|
||||
} //namespace libhiro
|
||||
|
||||
#endif //ifndef HIRO_H
|
||||
@@ -0,0 +1,25 @@
|
||||
void hiro_pbutton_tick(pButton *p) {
|
||||
if(p->self.on_tick) p->self.on_tick(Event(Event::Tick, 0, &p->self));
|
||||
}
|
||||
|
||||
void pButton::create(uint style, uint width, uint height, const char *text) {
|
||||
button = gtk_button_new_with_label(text ? text : "");
|
||||
gtk_widget_set_size_request(button, width, height);
|
||||
gtk_widget_show(button);
|
||||
g_signal_connect_swapped(G_OBJECT(button), "clicked", G_CALLBACK(hiro_pbutton_tick), (gpointer)this);
|
||||
}
|
||||
|
||||
void pButton::set_text(const char *text) {
|
||||
if(!button) return;
|
||||
gtk_button_set_label(GTK_BUTTON(button), text ? text : "");
|
||||
}
|
||||
|
||||
pButton::pButton(Button &self_) : pFormControl(self_), self(self_) {
|
||||
button = 0;
|
||||
}
|
||||
|
||||
/* internal */
|
||||
|
||||
GtkWidget* pButton::gtk_handle() {
|
||||
return button;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
class pButton : public pFormControl {
|
||||
public:
|
||||
Button &self;
|
||||
void create(uint style, uint width, uint height, const char *text = "");
|
||||
void set_text(const char *text = "");
|
||||
|
||||
pButton(Button&);
|
||||
|
||||
/* internal */
|
||||
GtkWidget *button;
|
||||
GtkWidget* gtk_handle();
|
||||
};
|
||||
@@ -0,0 +1,72 @@
|
||||
void hiro_pcanvas_expose(pCanvas *p) {
|
||||
uint32_t *f = p->fbuffer;
|
||||
uint32_t *r = p->rbuffer;
|
||||
for(uint y = p->canvas->allocation.height; y; y--) {
|
||||
for(uint x = p->canvas->allocation.width; x; x--) {
|
||||
uint32_t p = *f++;
|
||||
*r++ = ((p << 16) & 0xff0000) + (p & 0x00ff00) + ((p >> 16) & 0x0000ff);
|
||||
}
|
||||
}
|
||||
|
||||
gdk_draw_rgb_32_image(p->canvas->window,
|
||||
p->canvas->style->fg_gc[GTK_WIDGET_STATE(p->canvas)],
|
||||
0, 0, p->canvas->allocation.width, p->canvas->allocation.height,
|
||||
GDK_RGB_DITHER_NONE, (guchar*)p->rbuffer, p->bpitch);
|
||||
}
|
||||
|
||||
void pCanvas::create(uint style, uint width, uint height) {
|
||||
canvas = gtk_drawing_area_new();
|
||||
resize(width, height);
|
||||
GdkColor color;
|
||||
color.pixel = color.red = color.green = color.blue = 0;
|
||||
gtk_widget_modify_bg(canvas, GTK_STATE_NORMAL, &color);
|
||||
gtk_widget_set_double_buffered(canvas, false);
|
||||
gtk_widget_show(canvas);
|
||||
g_signal_connect_swapped(G_OBJECT(canvas), "expose_event", G_CALLBACK(hiro_pcanvas_expose), (gpointer)this);
|
||||
}
|
||||
|
||||
void pCanvas::redraw() {
|
||||
if(!canvas || !canvas->window) return;
|
||||
|
||||
GdkRectangle rect;
|
||||
rect.x = 0;
|
||||
rect.y = 0;
|
||||
rect.width = canvas->allocation.width;
|
||||
rect.height = canvas->allocation.height;
|
||||
gdk_window_invalidate_rect(canvas->window, &rect, true);
|
||||
}
|
||||
|
||||
uint32_t* pCanvas::buffer() {
|
||||
return fbuffer;
|
||||
}
|
||||
|
||||
pCanvas::pCanvas(Canvas &self_) : pFormControl(self_), self(self_) {
|
||||
canvas = 0;
|
||||
fbuffer = 0;
|
||||
rbuffer = 0;
|
||||
bpitch = 0;
|
||||
}
|
||||
|
||||
pCanvas::~pCanvas() {
|
||||
if(fbuffer) free(fbuffer);
|
||||
if(rbuffer) free(rbuffer);
|
||||
}
|
||||
|
||||
/* internal */
|
||||
|
||||
void pCanvas::resize(uint width, uint height) {
|
||||
if(fbuffer) free(fbuffer);
|
||||
if(rbuffer) free(rbuffer);
|
||||
|
||||
bpitch = width * sizeof(uint32_t);
|
||||
fbuffer = (uint32_t*)malloc(bpitch * height);
|
||||
rbuffer = (uint32_t*)malloc(bpitch * height);
|
||||
memset(fbuffer, 0, bpitch * height);
|
||||
memset(rbuffer, 0, bpitch * height);
|
||||
|
||||
pFormControl::resize(width, height);
|
||||
}
|
||||
|
||||
GtkWidget* pCanvas::gtk_handle() {
|
||||
return canvas;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
class pCanvas : public pFormControl {
|
||||
public:
|
||||
void create(uint style, uint width, uint height);
|
||||
void redraw();
|
||||
uint32_t* buffer();
|
||||
|
||||
Canvas &self;
|
||||
pCanvas(Canvas&);
|
||||
~pCanvas();
|
||||
|
||||
/* internal */
|
||||
GtkWidget *canvas;
|
||||
//GTK+ RGB drawing function draws in xBGR format, so two buffers are needed ...
|
||||
uint32_t *fbuffer; //one for the xRGB image
|
||||
uint32_t *rbuffer; //one for the xBGR image
|
||||
uint bpitch;
|
||||
void resize(uint width, uint height);
|
||||
GtkWidget* gtk_handle();
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
void hiro_pcheckbox_tick(pCheckbox *p) {
|
||||
if(p->self.on_tick) p->self.on_tick(Event(Event::Tick, p->checked(), &p->self));
|
||||
}
|
||||
|
||||
void pCheckbox::create(uint style, uint width, uint height, const char *text) {
|
||||
checkbox = gtk_check_button_new_with_label(text ? text : "");
|
||||
gtk_widget_set_size_request(checkbox, width, height);
|
||||
gtk_widget_show(checkbox);
|
||||
g_signal_connect_swapped(G_OBJECT(checkbox), "toggled", G_CALLBACK(hiro_pcheckbox_tick), (gpointer)this);
|
||||
}
|
||||
|
||||
void pCheckbox::set_text(const char *text) {
|
||||
if(!checkbox) return;
|
||||
gtk_button_set_label(GTK_BUTTON(checkbox), text ? text : "");
|
||||
}
|
||||
|
||||
void pCheckbox::check(bool state) {
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(checkbox), state ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
void pCheckbox::uncheck() {
|
||||
check(false);
|
||||
}
|
||||
|
||||
bool pCheckbox::checked() {
|
||||
return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(checkbox));
|
||||
}
|
||||
|
||||
pCheckbox::pCheckbox(Checkbox &self_) : pFormControl(self_), self(self_) {
|
||||
checkbox = 0;
|
||||
}
|
||||
|
||||
/* internal */
|
||||
|
||||
GtkWidget* pCheckbox::gtk_handle() {
|
||||
return checkbox;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
class pCheckbox : public pFormControl {
|
||||
public:
|
||||
void create(uint style, uint width, uint height, const char *text = "");
|
||||
void set_text(const char *text = "");
|
||||
void check(bool state = true);
|
||||
void uncheck();
|
||||
bool checked();
|
||||
|
||||
Checkbox &self;
|
||||
pCheckbox(Checkbox&);
|
||||
|
||||
/* internal */
|
||||
GtkWidget *checkbox;
|
||||
GtkWidget* gtk_handle();
|
||||
};
|
||||
@@ -0,0 +1,44 @@
|
||||
void hiro_pcombobox_change(pCombobox *p) {
|
||||
if(p->self.on_change) p->self.on_change(Event(Event::Change, p->get_selection(), &p->self));
|
||||
}
|
||||
|
||||
void pCombobox::create(uint style, uint width, uint height, const char *text) {
|
||||
combobox = gtk_combo_box_new_text();
|
||||
gtk_widget_set_size_request(combobox, width, height);
|
||||
gtk_widget_show(combobox);
|
||||
|
||||
g_signal_connect_swapped(G_OBJECT(combobox), "changed", G_CALLBACK(hiro_pcombobox_change), (gpointer)this);
|
||||
}
|
||||
|
||||
void pCombobox::add_item(const char *text) {
|
||||
if(!combobox) return;
|
||||
gtk_combo_box_append_text(GTK_COMBO_BOX(combobox), text ? text : "?");
|
||||
if(counter++ == 0) set_selection(0);
|
||||
}
|
||||
|
||||
int pCombobox::get_selection() {
|
||||
return gtk_combo_box_get_active(GTK_COMBO_BOX(combobox));
|
||||
}
|
||||
|
||||
void pCombobox::set_selection(int index) {
|
||||
gtk_combo_box_set_active(GTK_COMBO_BOX(combobox), index);
|
||||
}
|
||||
|
||||
void pCombobox::reset() {
|
||||
if(counter == 0) return;
|
||||
for(int i = counter - 1; i >= 0; i--) {
|
||||
gtk_combo_box_remove_text(GTK_COMBO_BOX(combobox), i);
|
||||
}
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
pCombobox::pCombobox(Combobox &self_) : pFormControl(self_), self(self_) {
|
||||
combobox = 0;
|
||||
counter = 0;
|
||||
}
|
||||
|
||||
/* internal */
|
||||
|
||||
GtkWidget* pCombobox::gtk_handle() {
|
||||
return combobox;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
class pCombobox : public pFormControl {
|
||||
public:
|
||||
void create(uint style, uint width, uint height, const char *text = "");
|
||||
void add_item(const char *text);
|
||||
int get_selection();
|
||||
void set_selection(int index);
|
||||
void reset();
|
||||
|
||||
Combobox &self;
|
||||
pCombobox(Combobox&);
|
||||
|
||||
/* internal */
|
||||
GtkWidget *combobox;
|
||||
uint counter;
|
||||
GtkWidget* gtk_handle();
|
||||
};
|
||||
@@ -0,0 +1,62 @@
|
||||
void pEditbox::create(uint style, uint width, uint height, const char *text) {
|
||||
multiline = bool(style & Editbox::Multiline);
|
||||
|
||||
if(multiline == false) {
|
||||
editbox = gtk_entry_new();
|
||||
if(style & Editbox::Readonly) { gtk_entry_set_editable(GTK_ENTRY(editbox), false); }
|
||||
gtk_entry_set_text(GTK_ENTRY(editbox), text ? text : "");
|
||||
gtk_widget_set_size_request(editbox, width, height);
|
||||
gtk_widget_show(editbox);
|
||||
} else {
|
||||
GtkPolicyType hscroll = (style & Editbox::HorizontalScrollAlways) ? GTK_POLICY_ALWAYS :
|
||||
(style & Editbox::HorizontalScrollNever) ? GTK_POLICY_NEVER :
|
||||
GTK_POLICY_AUTOMATIC;
|
||||
GtkPolicyType vscroll = (style & Editbox::VerticalScrollAlways) ? GTK_POLICY_ALWAYS :
|
||||
(style & Editbox::VerticalScrollNever) ? GTK_POLICY_NEVER :
|
||||
GTK_POLICY_AUTOMATIC;
|
||||
scrollbox = gtk_scrolled_window_new(0, 0);
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollbox), hscroll, vscroll);
|
||||
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrollbox), GTK_SHADOW_ETCHED_IN);
|
||||
gtk_widget_set_size_request(scrollbox, width, height);
|
||||
editbox = gtk_text_view_new();
|
||||
gtk_container_add(GTK_CONTAINER(scrollbox), editbox);
|
||||
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(editbox));
|
||||
if(style & Editbox::Readonly) { gtk_text_view_set_editable(GTK_TEXT_VIEW(editbox), false); }
|
||||
gtk_text_buffer_set_text(buffer, text ? text : "", -1);
|
||||
gtk_widget_show(editbox);
|
||||
gtk_widget_show(scrollbox);
|
||||
}
|
||||
}
|
||||
|
||||
void pEditbox::set_text(const char *text) {
|
||||
if(multiline == false) {
|
||||
gtk_entry_set_text(GTK_ENTRY(editbox), text);
|
||||
} else {
|
||||
gtk_text_buffer_set_text(buffer, text, -1);
|
||||
}
|
||||
}
|
||||
|
||||
uint pEditbox::get_text(char *text, uint length) {
|
||||
if(multiline == false) {
|
||||
const char *temp = gtk_entry_get_text(GTK_ENTRY(editbox));
|
||||
return strlcpy(text, temp ? temp : "", length);
|
||||
} else {
|
||||
GtkTextIter start, end;
|
||||
gtk_text_buffer_get_start_iter(buffer, &start);
|
||||
gtk_text_buffer_get_end_iter(buffer, &end);
|
||||
return strlcpy(text, gtk_text_buffer_get_text(buffer, &start, &end, true), length);
|
||||
}
|
||||
}
|
||||
|
||||
pEditbox::pEditbox(Editbox &self_) : pFormControl(self_), self(self_) {
|
||||
scrollbox = 0;
|
||||
editbox = 0;
|
||||
buffer = 0;
|
||||
multiline = false;
|
||||
}
|
||||
|
||||
/* internal */
|
||||
|
||||
GtkWidget* pEditbox::gtk_handle() {
|
||||
return multiline ? scrollbox : editbox;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
class pEditbox : public pFormControl {
|
||||
public:
|
||||
Editbox &self;
|
||||
void create(uint style, uint width, uint height, const char *text = "");
|
||||
uint get_text(char *text, uint length = -1U);
|
||||
void set_text(const char *text = "");
|
||||
|
||||
pEditbox(Editbox&);
|
||||
|
||||
/* internal */
|
||||
GtkWidget *scrollbox;
|
||||
GtkWidget *editbox;
|
||||
GtkTextBuffer *buffer;
|
||||
bool multiline;
|
||||
GtkWidget* gtk_handle();
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
void pFormControl::resize(uint width, uint height) {
|
||||
gtk_widget_set_size_request(gtk_handle(), width, height);
|
||||
}
|
||||
|
||||
void pFormControl::focus() {
|
||||
gtk_widget_grab_focus(gtk_handle());
|
||||
}
|
||||
|
||||
bool pFormControl::focused() {
|
||||
return GTK_WIDGET_HAS_FOCUS(gtk_handle());
|
||||
}
|
||||
|
||||
void pFormControl::enable(bool state) {
|
||||
gtk_widget_set_sensitive(gtk_handle(), state);
|
||||
}
|
||||
|
||||
void pFormControl::disable() {
|
||||
enable(false);
|
||||
}
|
||||
|
||||
bool pFormControl::enabled() {
|
||||
return GTK_WIDGET_SENSITIVE(gtk_handle());
|
||||
}
|
||||
|
||||
pFormControl::pFormControl(FormControl &self_) : pWidget(self_), self(self_) {
|
||||
}
|
||||
|
||||
/* internal */
|
||||
|
||||
GtkWidget* pFormControl::gtk_handle() {
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
class pFormControl : public pWidget {
|
||||
public:
|
||||
virtual void resize(uint width, uint height);
|
||||
void focus();
|
||||
bool focused();
|
||||
void enable(bool = true);
|
||||
void disable();
|
||||
bool enabled();
|
||||
|
||||
FormControl &self;
|
||||
pFormControl(FormControl&);
|
||||
|
||||
/* internal */
|
||||
virtual GtkWidget* gtk_handle();
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
void pFrame::create(uint style, uint width, uint height, const char *text) {
|
||||
frame = gtk_frame_new(text ? text : "");
|
||||
gtk_widget_set_size_request(frame, width, height);
|
||||
gtk_widget_show(frame);
|
||||
}
|
||||
|
||||
void pFrame::set_text(const char *text) {
|
||||
gtk_frame_set_label(GTK_FRAME(frame), text ? text : "");
|
||||
}
|
||||
|
||||
pFrame::pFrame(Frame &self_) : pFormControl(self_), self(self_) {
|
||||
frame = 0;
|
||||
}
|
||||
|
||||
/* internal */
|
||||
|
||||
GtkWidget* pFrame::gtk_handle() {
|
||||
return frame;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
class pFrame : public pFormControl {
|
||||
public:
|
||||
Frame &self;
|
||||
void create(uint style, uint width, uint height, const char *text = "");
|
||||
void set_text(const char *text = "");
|
||||
|
||||
pFrame(Frame&);
|
||||
|
||||
/* internal */
|
||||
GtkWidget *frame;
|
||||
GtkWidget* gtk_handle();
|
||||
};
|
||||
@@ -0,0 +1,121 @@
|
||||
#include "hiro.h"
|
||||
|
||||
#include <nall/algorithm.hpp>
|
||||
using nall::min;
|
||||
using nall::max;
|
||||
|
||||
namespace libhiro {
|
||||
|
||||
#include "keymap.cpp"
|
||||
#include "widget.cpp"
|
||||
#include "window.cpp"
|
||||
#include "menucontrol.cpp"
|
||||
#include "menugroup.cpp"
|
||||
#include "menuitem.cpp"
|
||||
#include "menucheckitem.cpp"
|
||||
#include "menuradioitem.cpp"
|
||||
#include "menuseparator.cpp"
|
||||
#include "formcontrol.cpp"
|
||||
#include "frame.cpp"
|
||||
#include "canvas.cpp"
|
||||
#include "label.cpp"
|
||||
#include "button.cpp"
|
||||
#include "checkbox.cpp"
|
||||
#include "radiobox.cpp"
|
||||
#include "editbox.cpp"
|
||||
#include "listbox.cpp"
|
||||
#include "combobox.cpp"
|
||||
#include "progressbar.cpp"
|
||||
#include "slider.cpp"
|
||||
|
||||
void pHiro::init() {
|
||||
//simulate passing argc, argv to gtk_init()
|
||||
int argc = 1;
|
||||
char **argv;
|
||||
argv = (char**)malloc(1 * sizeof(char*));
|
||||
argv[0] = (char*)malloc(64 * sizeof(char));
|
||||
strcpy(argv[0], "./hiro");
|
||||
gtk_init(&argc, &argv);
|
||||
free(argv[0]);
|
||||
free(argv);
|
||||
}
|
||||
|
||||
void pHiro::term() {
|
||||
}
|
||||
|
||||
bool pHiro::run() {
|
||||
gtk_main_iteration_do(false);
|
||||
return pending();
|
||||
}
|
||||
|
||||
bool pHiro::pending() {
|
||||
return gtk_events_pending();
|
||||
}
|
||||
|
||||
bool pHiro::file_load(Window *focus, char *filename, const char *filter, const char *path) {
|
||||
if(!filename) return false;
|
||||
strcpy(filename, "");
|
||||
|
||||
GtkWidget *dialog = gtk_file_chooser_dialog_new("Load File",
|
||||
focus ? GTK_WINDOW(focus->p.gtk_handle()) : (GtkWindow*)0,
|
||||
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
|
||||
(const gchar*)0);
|
||||
|
||||
if(path && *path) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path);
|
||||
|
||||
if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||
char *fn = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
||||
strcpy(filename, fn);
|
||||
g_free(fn);
|
||||
}
|
||||
|
||||
gtk_widget_destroy(dialog);
|
||||
return strcmp(filename, ""); //return true if filename exists
|
||||
}
|
||||
|
||||
bool pHiro::file_save(Window *focus, char *filename, const char *filter, const char *path) {
|
||||
if(!filename) return false;
|
||||
strcpy(filename, "");
|
||||
|
||||
GtkWidget *dialog = gtk_file_chooser_dialog_new("Save File",
|
||||
focus ? GTK_WINDOW(focus->p.gtk_handle()) : (GtkWindow*)0,
|
||||
GTK_FILE_CHOOSER_ACTION_SAVE,
|
||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
||||
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
|
||||
(const gchar*)0);
|
||||
|
||||
if(path && *path) gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(dialog), path);
|
||||
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
|
||||
|
||||
if(gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
|
||||
char *fn = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
|
||||
strcpy(filename, fn);
|
||||
g_free(fn);
|
||||
}
|
||||
|
||||
gtk_widget_destroy(dialog);
|
||||
return strcmp(filename, ""); //return true if filename exists
|
||||
}
|
||||
|
||||
uint pHiro::screen_width() {
|
||||
return gdk_screen_width();
|
||||
}
|
||||
|
||||
uint pHiro::screen_height() {
|
||||
return gdk_screen_height();
|
||||
}
|
||||
|
||||
pHiro& pHiro::handle() {
|
||||
return hiro().p;
|
||||
}
|
||||
|
||||
pHiro::pHiro(Hiro &self_) : self(self_) {
|
||||
}
|
||||
|
||||
pHiro& phiro() {
|
||||
return pHiro::handle();
|
||||
}
|
||||
|
||||
} //namespace libhiro
|
||||
@@ -0,0 +1,56 @@
|
||||
#ifndef HIRO_GTK_H
|
||||
#define HIRO_GTK_H
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include <gdk/gdkx.h>
|
||||
#include <gdk/gdkkeysyms.h>
|
||||
|
||||
namespace libhiro {
|
||||
|
||||
#include "widget.h"
|
||||
#include "window.h"
|
||||
#include "menucontrol.h"
|
||||
#include "menugroup.h"
|
||||
#include "menuitem.h"
|
||||
#include "menucheckitem.h"
|
||||
#include "menuradioitem.h"
|
||||
#include "menuseparator.h"
|
||||
#include "formcontrol.h"
|
||||
#include "frame.h"
|
||||
#include "canvas.h"
|
||||
#include "label.h"
|
||||
#include "button.h"
|
||||
#include "checkbox.h"
|
||||
#include "radiobox.h"
|
||||
#include "editbox.h"
|
||||
#include "listbox.h"
|
||||
#include "combobox.h"
|
||||
#include "progressbar.h"
|
||||
#include "slider.h"
|
||||
|
||||
class pHiro {
|
||||
public:
|
||||
Hiro &self;
|
||||
void init();
|
||||
void term();
|
||||
bool run();
|
||||
bool pending();
|
||||
|
||||
bool file_load(Window *focus, char *filename, const char *filter, const char *path);
|
||||
bool file_save(Window *focus, char *filename, const char *filter, const char *path);
|
||||
|
||||
uint screen_width();
|
||||
uint screen_height();
|
||||
|
||||
static pHiro& handle();
|
||||
pHiro(Hiro&);
|
||||
|
||||
/* internal */
|
||||
uint16_t translate_key(uint key);
|
||||
};
|
||||
|
||||
pHiro& phiro();
|
||||
|
||||
} //namespace libhiro
|
||||
|
||||
#endif //ifndef HIRO_GTK_H
|
||||
@@ -0,0 +1,188 @@
|
||||
uint16_t pHiro::translate_key(uint key) {
|
||||
switch(key) {
|
||||
case GDK_Escape: return keyboard::escape;
|
||||
|
||||
case GDK_F1: return keyboard::f1;
|
||||
case GDK_F2: return keyboard::f2;
|
||||
case GDK_F3: return keyboard::f3;
|
||||
case GDK_F4: return keyboard::f4;
|
||||
case GDK_F5: return keyboard::f5;
|
||||
case GDK_F6: return keyboard::f6;
|
||||
case GDK_F7: return keyboard::f7;
|
||||
case GDK_F8: return keyboard::f8;
|
||||
case GDK_F9: return keyboard::f9;
|
||||
case GDK_F10: return keyboard::f10;
|
||||
case GDK_F11: return keyboard::f11;
|
||||
case GDK_F12: return keyboard::f12;
|
||||
|
||||
case GDK_Print: return keyboard::print_screen;
|
||||
case GDK_Sys_Req: return keyboard::print_screen;
|
||||
case GDK_Scroll_Lock: return keyboard::scroll_lock;
|
||||
case GDK_Pause: return keyboard::pause;
|
||||
case GDK_Break: return keyboard::pause;
|
||||
|
||||
case GDK_grave: return keyboard::tilde;
|
||||
case GDK_asciitilde: return keyboard::tilde;
|
||||
|
||||
case GDK_1: return keyboard::num_1;
|
||||
case GDK_2: return keyboard::num_2;
|
||||
case GDK_3: return keyboard::num_3;
|
||||
case GDK_4: return keyboard::num_4;
|
||||
case GDK_5: return keyboard::num_5;
|
||||
case GDK_6: return keyboard::num_6;
|
||||
case GDK_7: return keyboard::num_7;
|
||||
case GDK_8: return keyboard::num_8;
|
||||
case GDK_9: return keyboard::num_9;
|
||||
case GDK_0: return keyboard::num_0;
|
||||
|
||||
case GDK_exclam: return keyboard::num_1;
|
||||
case GDK_at: return keyboard::num_2;
|
||||
case GDK_numbersign: return keyboard::num_3;
|
||||
case GDK_dollar: return keyboard::num_4;
|
||||
case GDK_percent: return keyboard::num_5;
|
||||
case GDK_asciicircum: return keyboard::num_6;
|
||||
case GDK_ampersand: return keyboard::num_7;
|
||||
case GDK_asterisk: return keyboard::num_8;
|
||||
case GDK_parenleft: return keyboard::num_9;
|
||||
case GDK_parenright: return keyboard::num_0;
|
||||
|
||||
case GDK_minus: return keyboard::dash;
|
||||
case GDK_underscore: return keyboard::dash;
|
||||
case GDK_equal: return keyboard::equal;
|
||||
case GDK_plus: return keyboard::equal;
|
||||
case GDK_BackSpace: return keyboard::backspace;
|
||||
|
||||
case GDK_Insert: return keyboard::insert;
|
||||
case GDK_Delete: return keyboard::delete_;
|
||||
case GDK_Home: return keyboard::home;
|
||||
case GDK_End: return keyboard::end;
|
||||
case GDK_Page_Up: return keyboard::page_up;
|
||||
case GDK_Page_Down: return keyboard::page_down;
|
||||
|
||||
case GDK_a: return keyboard::a;
|
||||
case GDK_b: return keyboard::b;
|
||||
case GDK_c: return keyboard::c;
|
||||
case GDK_d: return keyboard::d;
|
||||
case GDK_e: return keyboard::e;
|
||||
case GDK_f: return keyboard::f;
|
||||
case GDK_g: return keyboard::g;
|
||||
case GDK_h: return keyboard::h;
|
||||
case GDK_i: return keyboard::i;
|
||||
case GDK_j: return keyboard::j;
|
||||
case GDK_k: return keyboard::k;
|
||||
case GDK_l: return keyboard::l;
|
||||
case GDK_m: return keyboard::m;
|
||||
case GDK_n: return keyboard::n;
|
||||
case GDK_o: return keyboard::o;
|
||||
case GDK_p: return keyboard::p;
|
||||
case GDK_q: return keyboard::q;
|
||||
case GDK_r: return keyboard::r;
|
||||
case GDK_s: return keyboard::s;
|
||||
case GDK_t: return keyboard::t;
|
||||
case GDK_u: return keyboard::u;
|
||||
case GDK_v: return keyboard::v;
|
||||
case GDK_w: return keyboard::w;
|
||||
case GDK_x: return keyboard::x;
|
||||
case GDK_y: return keyboard::y;
|
||||
case GDK_z: return keyboard::z;
|
||||
|
||||
case GDK_A: return keyboard::a;
|
||||
case GDK_B: return keyboard::b;
|
||||
case GDK_C: return keyboard::c;
|
||||
case GDK_D: return keyboard::d;
|
||||
case GDK_E: return keyboard::e;
|
||||
case GDK_F: return keyboard::f;
|
||||
case GDK_G: return keyboard::g;
|
||||
case GDK_H: return keyboard::h;
|
||||
case GDK_I: return keyboard::i;
|
||||
case GDK_J: return keyboard::j;
|
||||
case GDK_K: return keyboard::k;
|
||||
case GDK_L: return keyboard::l;
|
||||
case GDK_M: return keyboard::m;
|
||||
case GDK_N: return keyboard::n;
|
||||
case GDK_O: return keyboard::o;
|
||||
case GDK_P: return keyboard::p;
|
||||
case GDK_Q: return keyboard::q;
|
||||
case GDK_R: return keyboard::r;
|
||||
case GDK_S: return keyboard::s;
|
||||
case GDK_T: return keyboard::t;
|
||||
case GDK_U: return keyboard::u;
|
||||
case GDK_V: return keyboard::v;
|
||||
case GDK_W: return keyboard::w;
|
||||
case GDK_X: return keyboard::x;
|
||||
case GDK_Y: return keyboard::y;
|
||||
case GDK_Z: return keyboard::z;
|
||||
|
||||
case GDK_bracketleft: return keyboard::lbracket;
|
||||
case GDK_bracketright: return keyboard::rbracket;
|
||||
case GDK_backslash: return keyboard::backslash;
|
||||
case GDK_semicolon: return keyboard::semicolon;
|
||||
case GDK_apostrophe: return keyboard::apostrophe;
|
||||
case GDK_comma: return keyboard::comma;
|
||||
case GDK_period: return keyboard::period;
|
||||
case GDK_slash: return keyboard::slash;
|
||||
|
||||
case GDK_braceleft: return keyboard::lbracket;
|
||||
case GDK_braceright: return keyboard::rbracket;
|
||||
case GDK_bar: return keyboard::backslash;
|
||||
case GDK_colon: return keyboard::semicolon;
|
||||
case GDK_quotedbl: return keyboard::apostrophe;
|
||||
case GDK_less: return keyboard::comma;
|
||||
case GDK_greater: return keyboard::period;
|
||||
case GDK_question: return keyboard::slash;
|
||||
|
||||
case GDK_KP_1: return keyboard::pad_1;
|
||||
case GDK_KP_2: return keyboard::pad_2;
|
||||
case GDK_KP_3: return keyboard::pad_3;
|
||||
case GDK_KP_4: return keyboard::pad_4;
|
||||
case GDK_KP_5: return keyboard::pad_5;
|
||||
case GDK_KP_6: return keyboard::pad_6;
|
||||
case GDK_KP_7: return keyboard::pad_7;
|
||||
case GDK_KP_8: return keyboard::pad_8;
|
||||
case GDK_KP_9: return keyboard::pad_9;
|
||||
case GDK_KP_0: return keyboard::pad_0;
|
||||
case GDK_KP_Decimal: return keyboard::point;
|
||||
|
||||
case GDK_KP_End: return keyboard::pad_1;
|
||||
case GDK_KP_Down: return keyboard::pad_2;
|
||||
case GDK_KP_Page_Down: return keyboard::pad_3;
|
||||
case GDK_KP_Left: return keyboard::pad_4;
|
||||
case GDK_KP_Begin: return keyboard::pad_5;
|
||||
case GDK_KP_Right: return keyboard::pad_6;
|
||||
case GDK_KP_Home: return keyboard::pad_7;
|
||||
case GDK_KP_Up: return keyboard::pad_8;
|
||||
case GDK_KP_Page_Up: return keyboard::pad_9;
|
||||
case GDK_KP_Insert: return keyboard::pad_0;
|
||||
case GDK_KP_Delete: return keyboard::point;
|
||||
|
||||
case GDK_KP_Add: return keyboard::add;
|
||||
case GDK_KP_Subtract: return keyboard::subtract;
|
||||
case GDK_KP_Multiply: return keyboard::multiply;
|
||||
case GDK_KP_Divide: return keyboard::divide;
|
||||
case GDK_KP_Enter: return keyboard::enter;
|
||||
|
||||
case GDK_Num_Lock: return keyboard::num_lock;
|
||||
case GDK_Caps_Lock: return keyboard::caps_lock;
|
||||
|
||||
case GDK_Up: return keyboard::up;
|
||||
case GDK_Down: return keyboard::down;
|
||||
case GDK_Left: return keyboard::left;
|
||||
case GDK_Right: return keyboard::right;
|
||||
|
||||
case GDK_Tab: return keyboard::tab;
|
||||
case GDK_Return: return keyboard::return_;
|
||||
case GDK_space: return keyboard::spacebar;
|
||||
|
||||
case GDK_Control_L: return keyboard::lctrl;
|
||||
case GDK_Control_R: return keyboard::rctrl;
|
||||
case GDK_Alt_L: return keyboard::lalt;
|
||||
case GDK_Alt_R: return keyboard::ralt;
|
||||
case GDK_Shift_L: return keyboard::lshift;
|
||||
case GDK_Shift_R: return keyboard::rshift;
|
||||
case GDK_Super_L: return keyboard::lsuper;
|
||||
case GDK_Super_R: return keyboard::rsuper;
|
||||
case GDK_Menu: return keyboard::menu;
|
||||
}
|
||||
|
||||
return keyboard::none;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
void pLabel::create(uint style, uint width, uint height, const char *text) {
|
||||
label = gtk_label_new(text ? text : "");
|
||||
gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
|
||||
gtk_widget_set_size_request(label, width, height);
|
||||
gtk_widget_show(label);
|
||||
}
|
||||
|
||||
void pLabel::set_text(const char *text) {
|
||||
if(!label) return;
|
||||
gtk_label_set_label(GTK_LABEL(label), text ? text : "");
|
||||
}
|
||||
|
||||
pLabel::pLabel(Label &self_) : pFormControl(self_), self(self_) {
|
||||
label = 0;
|
||||
}
|
||||
|
||||
/* internal */
|
||||
|
||||
GtkWidget* pLabel::gtk_handle() {
|
||||
return label;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
class pLabel : public pFormControl {
|
||||
public:
|
||||
Label &self;
|
||||
void create(uint style, uint width, uint height, const char *text = "");
|
||||
void set_text(const char *text = "");
|
||||
|
||||
pLabel(Label&);
|
||||
|
||||
/* internal */
|
||||
GtkWidget *label;
|
||||
GtkWidget* gtk_handle();
|
||||
};
|
||||
@@ -0,0 +1,135 @@
|
||||
void hiro_plistbox_change(pListbox *p) {
|
||||
if(p->listbox_selection == p->get_selection()) return;
|
||||
if(p->self.on_change) p->self.on_change(Event(Event::Change, p->listbox_selection = p->get_selection(), &p->self));
|
||||
}
|
||||
|
||||
void hiro_plistbox_activate(pListbox *p) {
|
||||
if(p->self.on_activate) p->self.on_activate(Event(Event::Activate, p->listbox_selection = p->get_selection(), &p->self));
|
||||
}
|
||||
|
||||
void pListbox::create(uint style, uint width, uint height, const char *columns, const char *text) {
|
||||
bool header = style & Listbox::Header;
|
||||
GtkPolicyType hscroll = (style & Listbox::HorizontalScrollAlways) ? GTK_POLICY_ALWAYS :
|
||||
(style & Listbox::HorizontalScrollNever) ? GTK_POLICY_NEVER :
|
||||
GTK_POLICY_AUTOMATIC;
|
||||
GtkPolicyType vscroll = (style & Listbox::VerticalScrollAlways) ? GTK_POLICY_ALWAYS :
|
||||
(style & Listbox::VerticalScrollNever) ? GTK_POLICY_NEVER :
|
||||
GTK_POLICY_AUTOMATIC;
|
||||
|
||||
scrollbox = gtk_scrolled_window_new(0, 0);
|
||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollbox), hscroll, vscroll);
|
||||
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrollbox), GTK_SHADOW_ETCHED_IN);
|
||||
|
||||
lstring list;
|
||||
split(list, "\t", columns);
|
||||
|
||||
GType *v = (GType*)malloc(count(list) * sizeof(GType));
|
||||
for(uint i = 0; i < count(list); i++) v[i] = G_TYPE_STRING;
|
||||
store = gtk_list_store_newv(count(list), v);
|
||||
free(v);
|
||||
|
||||
listbox = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
|
||||
gtk_container_add(GTK_CONTAINER(scrollbox), listbox);
|
||||
g_object_unref(G_OBJECT(store));
|
||||
gtk_widget_set_size_request(scrollbox, width, height);
|
||||
gtk_widget_show(listbox);
|
||||
gtk_widget_show(scrollbox);
|
||||
|
||||
//alternate colors for each listbox entry if there are multiple columns ...
|
||||
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(listbox), count(list) >= 2 ? true : false);
|
||||
for(uint i = 0; i < count(list); i++) {
|
||||
renderer = gtk_cell_renderer_text_new();
|
||||
column = gtk_tree_view_column_new_with_attributes(list[i], renderer, "text", i, (void*)0);
|
||||
column_list[column_list.size()] = column;
|
||||
gtk_tree_view_append_column(GTK_TREE_VIEW(listbox), column);
|
||||
}
|
||||
|
||||
if(text && *text) {
|
||||
split(list, "\n", text);
|
||||
for(uint i = 0; i < count(list); i++) add_item(list[i]);
|
||||
}
|
||||
|
||||
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(listbox), header);
|
||||
autosize_columns();
|
||||
|
||||
g_signal_connect_swapped(G_OBJECT(listbox), "cursor-changed", G_CALLBACK(hiro_plistbox_change), (gpointer)this);
|
||||
g_signal_connect_swapped(G_OBJECT(listbox), "row-activated", G_CALLBACK(hiro_plistbox_activate), (gpointer)this);
|
||||
}
|
||||
|
||||
void pListbox::autosize_columns() {
|
||||
gtk_tree_view_columns_autosize(GTK_TREE_VIEW(listbox));
|
||||
}
|
||||
|
||||
void pListbox::set_column_width(uint column, uint width) {
|
||||
gtk_tree_view_column_set_min_width(column_list[column], width);
|
||||
gtk_tree_view_column_set_max_width(column_list[column], width);
|
||||
}
|
||||
|
||||
void pListbox::add_item(const char *text) {
|
||||
lstring list;
|
||||
split(list, "\t", text);
|
||||
gtk_list_store_append(store, &iter);
|
||||
for(uint i = 0; i < count(list); i++) {
|
||||
gtk_list_store_set(store, &iter, i, list[i](), -1);
|
||||
}
|
||||
}
|
||||
|
||||
void pListbox::set_item(uint index, const char *text) {
|
||||
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(listbox));
|
||||
for(uint i = 0; i <= index; i++) {
|
||||
i == 0 ?
|
||||
gtk_tree_model_get_iter_first(model, &iter) :
|
||||
gtk_tree_model_iter_next(model, &iter);
|
||||
}
|
||||
|
||||
lstring list;
|
||||
split(list, "\t", text);
|
||||
for(uint i = 0; i < count(list); i++) {
|
||||
gtk_list_store_set(store, &iter, i, list[i](), -1);
|
||||
}
|
||||
}
|
||||
|
||||
int pListbox::get_selection() {
|
||||
GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(listbox));
|
||||
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(listbox));
|
||||
if(gtk_tree_model_get_iter_first(model, &iter) == false) { return -1; }
|
||||
if(gtk_tree_selection_iter_is_selected(selection, &iter) == true) { return 0; }
|
||||
for(uint i = 1; i < 100000; i++) {
|
||||
if(gtk_tree_model_iter_next(model, &iter) == false) { return -1; }
|
||||
if(gtk_tree_selection_iter_is_selected(selection, &iter) == true) { return i; }
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void pListbox::set_selection(int index) {
|
||||
int current = get_selection();
|
||||
GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(listbox));
|
||||
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(listbox));
|
||||
gtk_tree_selection_unselect_all(selection);
|
||||
if(index < 0) { goto end; }
|
||||
if(gtk_tree_model_get_iter_first(model, &iter) == false) { goto end; }
|
||||
if(index == 0) { gtk_tree_selection_select_iter(selection, &iter); goto end; }
|
||||
for(uint i = 1; i < 100000; i++) {
|
||||
if(gtk_tree_model_iter_next(model, &iter) == false) { goto end; }
|
||||
if(index == i) { gtk_tree_selection_select_iter(selection, &iter); goto end; }
|
||||
}
|
||||
end:
|
||||
if(current != index) ;//{ owner->message(Message::Changed, (uintptr_t)this); }
|
||||
}
|
||||
|
||||
void pListbox::reset() {
|
||||
gtk_list_store_clear(GTK_LIST_STORE(store));
|
||||
gtk_tree_view_set_model(GTK_TREE_VIEW(listbox), GTK_TREE_MODEL(store));
|
||||
}
|
||||
|
||||
pListbox::pListbox(Listbox &self_) : pFormControl(self_), self(self_) {
|
||||
scrollbox = 0;
|
||||
listbox = 0;
|
||||
listbox_selection = -1;
|
||||
}
|
||||
|
||||
/* internal */
|
||||
|
||||
GtkWidget* pListbox::gtk_handle() {
|
||||
return scrollbox;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
class pListbox : public pFormControl {
|
||||
public:
|
||||
void create(uint style, uint width, uint height, const char *columns = "", const char *text = "");
|
||||
void autosize_columns();
|
||||
void set_column_width(uint column, uint width);
|
||||
void add_item(const char *text);
|
||||
void set_item(uint index, const char *text);
|
||||
int get_selection();
|
||||
void set_selection(int index);
|
||||
void reset();
|
||||
|
||||
Listbox &self;
|
||||
pListbox(Listbox&);
|
||||
|
||||
/* internal */
|
||||
GtkWidget *scrollbox;
|
||||
GtkWidget *listbox;
|
||||
GtkListStore *store;
|
||||
GtkCellRenderer *renderer;
|
||||
GtkTreeViewColumn *column;
|
||||
array<GtkTreeViewColumn*> column_list;
|
||||
GtkTreeIter iter;
|
||||
int listbox_selection;
|
||||
GtkWidget* gtk_handle();
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
void hiro_pmenucheckitem_tick(pMenuCheckItem *p) {
|
||||
if(p->self.on_tick) p->self.on_tick(Event(Event::Tick, p->checked(), &p->self));
|
||||
}
|
||||
|
||||
void pMenuCheckItem::create(const char *text) {
|
||||
item = gtk_check_menu_item_new_with_label(text ? text : "?");
|
||||
gtk_widget_show(item);
|
||||
g_signal_connect_swapped(G_OBJECT(item), "toggled", G_CALLBACK(hiro_pmenucheckitem_tick), (gpointer)this);
|
||||
}
|
||||
|
||||
void pMenuCheckItem::check(bool state) {
|
||||
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), state ? TRUE : FALSE);
|
||||
}
|
||||
|
||||
void pMenuCheckItem::uncheck() {
|
||||
check(false);
|
||||
}
|
||||
|
||||
bool pMenuCheckItem::checked() {
|
||||
return gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item));
|
||||
}
|
||||
|
||||
pMenuCheckItem::pMenuCheckItem(MenuCheckItem &self_) : pMenuControl(self_), self(self_) {
|
||||
item = 0;
|
||||
}
|
||||
|
||||
/* internal */
|
||||
|
||||
GtkWidget* pMenuCheckItem::gtk_handle() {
|
||||
return item;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
class pMenuCheckItem : public pMenuControl {
|
||||
public:
|
||||
void create(const char *text = "");
|
||||
void check(bool state = true);
|
||||
void uncheck();
|
||||
bool checked();
|
||||
|
||||
MenuCheckItem &self;
|
||||
pMenuCheckItem(MenuCheckItem&);
|
||||
|
||||
/* internal */
|
||||
GtkWidget *item;
|
||||
GtkWidget* gtk_handle();
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
void pMenuControl::enable(bool state) {
|
||||
gtk_widget_set_sensitive(gtk_handle(), state);
|
||||
}
|
||||
|
||||
void pMenuControl::disable() {
|
||||
enable(false);
|
||||
}
|
||||
|
||||
bool pMenuControl::enabled() {
|
||||
return GTK_WIDGET_SENSITIVE(gtk_handle());
|
||||
}
|
||||
|
||||
pMenuControl::pMenuControl(MenuControl &self_) : pWidget(self_), self(self_) {
|
||||
}
|
||||
|
||||
/* internal */
|
||||
|
||||
GtkWidget* pMenuControl::gtk_handle() {
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
class pMenuControl : public pWidget {
|
||||
public:
|
||||
void enable(bool = true);
|
||||
void disable();
|
||||
bool enabled();
|
||||
|
||||
MenuControl &self;
|
||||
pMenuControl(MenuControl&);
|
||||
|
||||
/* internal */
|
||||
virtual GtkWidget* gtk_handle();
|
||||
};
|
||||
@@ -0,0 +1,21 @@
|
||||
void pMenuGroup::create(const char *text) {
|
||||
group = gtk_menu_new();
|
||||
item = gtk_menu_item_new_with_label(text ? text : "");
|
||||
gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), group);
|
||||
gtk_widget_show(item);
|
||||
}
|
||||
|
||||
void pMenuGroup::attach(MenuControl &menucontrol) {
|
||||
gtk_menu_shell_append(GTK_MENU_SHELL(group), menucontrol.p.gtk_handle());
|
||||
}
|
||||
|
||||
pMenuGroup::pMenuGroup(MenuGroup &self_) : pMenuControl(self_), self(self_) {
|
||||
group = 0;
|
||||
item = 0;
|
||||
}
|
||||
|
||||
/* internal */
|
||||
|
||||
GtkWidget* pMenuGroup::gtk_handle() {
|
||||
return item;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
class pMenuGroup : public pMenuControl {
|
||||
public:
|
||||
MenuGroup &self;
|
||||
void create(const char *text);
|
||||
void attach(MenuControl &menucontrol);
|
||||
|
||||
pMenuGroup(MenuGroup&);
|
||||
|
||||
/* internal */
|
||||
GtkWidget *group;
|
||||
GtkWidget *item;
|
||||
GtkWidget* gtk_handle();
|
||||
};
|
||||
@@ -0,0 +1,19 @@
|
||||
void hiro_pmenuitem_tick(pMenuItem *p) {
|
||||
if(p->self.on_tick) p->self.on_tick(Event(Event::Tick, 0, &p->self));
|
||||
}
|
||||
|
||||
void pMenuItem::create(const char *text) {
|
||||
item = gtk_menu_item_new_with_label(text ? text : "");
|
||||
g_signal_connect_swapped(G_OBJECT(item), "activate", G_CALLBACK(hiro_pmenuitem_tick), (gpointer)this);
|
||||
gtk_widget_show(item);
|
||||
}
|
||||
|
||||
pMenuItem::pMenuItem(MenuItem &self_) : pMenuControl(self_), self(self_) {
|
||||
item = 0;
|
||||
}
|
||||
|
||||
/* internal */
|
||||
|
||||
GtkWidget* pMenuItem::gtk_handle() {
|
||||
return item;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
class pMenuItem : public pMenuControl {
|
||||
public:
|
||||
void create(const char *text = "");
|
||||
|
||||
MenuItem &self;
|
||||
pMenuItem(MenuItem&);
|
||||
|
||||
/* internal */
|
||||
GtkWidget *item;
|
||||
GtkWidget* gtk_handle();
|
||||
};
|
||||
@@ -0,0 +1,33 @@
|
||||
void hiro_pmenuradioitem_tick(pMenuRadioItem *p) {
|
||||
//GTK+ sends two messages: one for the activated radio item,
|
||||
//and one for the deactivated radio item. ignore the latter.
|
||||
if(p->checked() && p->self.on_tick) p->self.on_tick(Event(Event::Tick, 0, &p->self));
|
||||
}
|
||||
|
||||
void pMenuRadioItem::create(MenuRadioItemGroup &group, const char *text) {
|
||||
if(group.size() == 0 || group[0] == &self) {
|
||||
item = gtk_radio_menu_item_new_with_label(0, text ? text : "?");
|
||||
} else {
|
||||
item = gtk_radio_menu_item_new_with_label_from_widget(GTK_RADIO_MENU_ITEM(group[0]->p.gtk_handle()), text ? text : "");
|
||||
}
|
||||
gtk_widget_show(item);
|
||||
g_signal_connect_swapped(G_OBJECT(item), "toggled", G_CALLBACK(hiro_pmenuradioitem_tick), (gpointer)this);
|
||||
}
|
||||
|
||||
void pMenuRadioItem::check() {
|
||||
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item), TRUE);
|
||||
}
|
||||
|
||||
bool pMenuRadioItem::checked() {
|
||||
return gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(item));
|
||||
}
|
||||
|
||||
pMenuRadioItem::pMenuRadioItem(MenuRadioItem &self_) : pMenuControl(self_), self(self_) {
|
||||
item = 0;
|
||||
}
|
||||
|
||||
/* internal */
|
||||
|
||||
GtkWidget* pMenuRadioItem::gtk_handle() {
|
||||
return item;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
class pMenuRadioItem : public pMenuControl {
|
||||
public:
|
||||
void create(MenuRadioItemGroup &group, const char *text = "");
|
||||
void check();
|
||||
bool checked();
|
||||
|
||||
MenuRadioItem &self;
|
||||
pMenuRadioItem(MenuRadioItem&);
|
||||
|
||||
/* internal */
|
||||
GtkWidget *item;
|
||||
GtkWidget* gtk_handle();
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
void pMenuSeparator::create() {
|
||||
item = gtk_separator_menu_item_new();
|
||||
gtk_widget_show(item);
|
||||
}
|
||||
|
||||
pMenuSeparator::pMenuSeparator(MenuSeparator &self_) : pMenuControl(self_), self(self_) {
|
||||
item = 0;
|
||||
}
|
||||
|
||||
/* internal */
|
||||
|
||||
GtkWidget* pMenuSeparator::gtk_handle() {
|
||||
return item;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
class pMenuSeparator : public pMenuControl {
|
||||
public:
|
||||
MenuSeparator &self;
|
||||
void create();
|
||||
|
||||
pMenuSeparator(MenuSeparator&);
|
||||
|
||||
/* internal */
|
||||
GtkWidget *item;
|
||||
GtkWidget* gtk_handle();
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
void pProgressbar::create(uint style, uint width, uint height) {
|
||||
progressbar = gtk_progress_bar_new();
|
||||
gtk_widget_set_size_request(progressbar, width, height);
|
||||
gtk_widget_show(progressbar);
|
||||
}
|
||||
|
||||
uint pProgressbar::get_progress() {
|
||||
uint progress = (uint)(gtk_progress_bar_get_fraction(GTK_PROGRESS_BAR(progressbar)) * 100.0);
|
||||
return max(0U, min(progress, 100U));
|
||||
}
|
||||
|
||||
void pProgressbar::set_progress(uint progress) {
|
||||
progress = max(0U, min(progress, 100U));
|
||||
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progressbar), (double)progress / 100.0);
|
||||
}
|
||||
|
||||
pProgressbar::pProgressbar(Progressbar &self_) : pFormControl(self_), self(self_) {
|
||||
progressbar = 0;
|
||||
}
|
||||
|
||||
/* internal */
|
||||
|
||||
GtkWidget* pProgressbar::gtk_handle() {
|
||||
return progressbar;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
class pProgressbar : public pFormControl {
|
||||
public:
|
||||
Progressbar &self;
|
||||
void create(uint style, uint width, uint height);
|
||||
uint get_progress();
|
||||
void set_progress(uint progress);
|
||||
|
||||
pProgressbar(Progressbar&);
|
||||
|
||||
/* internal */
|
||||
GtkWidget *progressbar;
|
||||
GtkWidget* gtk_handle();
|
||||
};
|
||||
@@ -0,0 +1,39 @@
|
||||
void hiro_pradiobox_tick(pRadiobox *p) {
|
||||
//GTK+ sends two messages: one for the activated radiobox,
|
||||
//and one for the deactivated radiobox. ignore the latter.
|
||||
if(p->checked() && p->self.on_tick) p->self.on_tick(Event(Event::Tick, 0, &p->self));
|
||||
}
|
||||
|
||||
void pRadiobox::create(RadioboxGroup &group, uint style, uint width, uint height, const char *text) {
|
||||
if(group.size() == 0 || group[0] == &self) {
|
||||
radiobox = gtk_radio_button_new_with_label(0, text ? text : "");
|
||||
} else {
|
||||
radiobox = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(group[0]->p.gtk_handle()), text ? text : "");
|
||||
}
|
||||
gtk_widget_set_size_request(radiobox, width, height);
|
||||
gtk_widget_show(radiobox);
|
||||
g_signal_connect_swapped(G_OBJECT(radiobox), "toggled", G_CALLBACK(hiro_pradiobox_tick), (gpointer)this);
|
||||
}
|
||||
|
||||
void pRadiobox::set_text(const char *text) {
|
||||
if(!radiobox) return;
|
||||
gtk_button_set_label(GTK_BUTTON(radiobox), text ? text : "");
|
||||
}
|
||||
|
||||
void pRadiobox::check() {
|
||||
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radiobox), TRUE);
|
||||
}
|
||||
|
||||
bool pRadiobox::checked() {
|
||||
return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radiobox));
|
||||
}
|
||||
|
||||
pRadiobox::pRadiobox(Radiobox &self_) : pFormControl(self), self(self_) {
|
||||
radiobox = 0;
|
||||
}
|
||||
|
||||
/* internal */
|
||||
|
||||
GtkWidget* pRadiobox::gtk_handle() {
|
||||
return radiobox;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
class pRadiobox : public pFormControl {
|
||||
public:
|
||||
void create(RadioboxGroup &group, uint style, uint width, uint height, const char *text = "");
|
||||
void set_text(const char *text = "");
|
||||
void check();
|
||||
bool checked();
|
||||
|
||||
Radiobox &self;
|
||||
pRadiobox(Radiobox&);
|
||||
|
||||
/* internal */
|
||||
GtkWidget *radiobox;
|
||||
GtkWidget* gtk_handle();
|
||||
};
|
||||
@@ -0,0 +1,36 @@
|
||||
void hiro_pslider_change(pSlider *p) {
|
||||
if(p->slider_position == p->get_position()) return;
|
||||
if(p->self.on_change) p->self.on_change(Event(Event::Change, p->slider_position = p->get_position(), &p->self));
|
||||
}
|
||||
|
||||
void pSlider::create(uint style, uint width, uint height, uint length) {
|
||||
if(length < 1) length = 1;
|
||||
if(style & Slider::Vertical) {
|
||||
slider = gtk_vscale_new_with_range(0, length - 1, 1);
|
||||
} else {
|
||||
slider = gtk_hscale_new_with_range(0, length - 1, 1);
|
||||
}
|
||||
gtk_scale_set_draw_value(GTK_SCALE(slider), FALSE);
|
||||
gtk_widget_set_size_request(slider, width, height);
|
||||
gtk_widget_show(slider);
|
||||
g_signal_connect_swapped(G_OBJECT(slider), "value-changed", G_CALLBACK(hiro_pslider_change), (gpointer)this);
|
||||
}
|
||||
|
||||
uint pSlider::get_position() {
|
||||
return (uint)gtk_range_get_value(GTK_RANGE(slider));
|
||||
}
|
||||
|
||||
void pSlider::set_position(uint position) {
|
||||
gtk_range_set_value(GTK_RANGE(slider), position);
|
||||
}
|
||||
|
||||
pSlider::pSlider(Slider &self_) : pFormControl(self_), self(self_) {
|
||||
slider = 0;
|
||||
slider_position = 0;
|
||||
}
|
||||
|
||||
/* internal */
|
||||
|
||||
GtkWidget* pSlider::gtk_handle() {
|
||||
return slider;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
class pSlider : public pFormControl {
|
||||
public:
|
||||
void create(uint style, uint width, uint height, uint length);
|
||||
uint get_position();
|
||||
void set_position(uint position);
|
||||
|
||||
Slider &self;
|
||||
pSlider(Slider&);
|
||||
|
||||
/* internal */
|
||||
GtkWidget *slider;
|
||||
uint slider_position;
|
||||
GtkWidget* gtk_handle();
|
||||
};
|
||||
@@ -0,0 +1,24 @@
|
||||
void pWidget::show(bool state) {
|
||||
state ? gtk_widget_show(gtk_handle()) : gtk_widget_hide(gtk_handle());
|
||||
}
|
||||
|
||||
void pWidget::hide() {
|
||||
show(false);
|
||||
}
|
||||
|
||||
bool pWidget::visible() {
|
||||
return GTK_WIDGET_VISIBLE(gtk_handle());
|
||||
}
|
||||
|
||||
uintptr_t pWidget::handle() {
|
||||
return GDK_WINDOW_XID(gtk_handle()->window);
|
||||
}
|
||||
|
||||
pWidget::pWidget(Widget &self_) : self(self_) {
|
||||
}
|
||||
|
||||
/* internal */
|
||||
|
||||
GtkWidget* pWidget::gtk_handle() {
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
class pWidget {
|
||||
public:
|
||||
void show(bool = true);
|
||||
void hide();
|
||||
bool visible();
|
||||
uintptr_t handle();
|
||||
|
||||
Widget &self;
|
||||
pWidget(Widget&);
|
||||
|
||||
/* internal */
|
||||
virtual GtkWidget* gtk_handle();
|
||||
};
|
||||
@@ -0,0 +1,262 @@
|
||||
gint hiro_pwindow_close(pWindow *p) {
|
||||
uintptr_t r = p->self.on_close ? p->self.on_close(Event(Event::Close, 0, &p->self)) : true;
|
||||
return !bool(r);
|
||||
}
|
||||
|
||||
gint hiro_pwindow_keydown(GtkWidget *w, GdkEventKey *key, pWindow *p) {
|
||||
if(p && p->self.on_keydown) p->self.on_keydown(Event(Event::KeyDown, phiro().translate_key(key->keyval), &p->self));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
gint hiro_pwindow_keyup(GtkWidget *w, GdkEventKey *key, pWindow *p) {
|
||||
if(p && p->self.on_keyup) p->self.on_keyup(Event(Event::KeyUp, phiro().translate_key(key->keyval), &p->self));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void pWindow::create(uint style, uint width, uint height, const char *text) {
|
||||
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
|
||||
gtk_window_set_title(GTK_WINDOW(window), text ? text : "");
|
||||
gtk_window_set_resizable(GTK_WINDOW(window), false);
|
||||
if(style & Window::AutoCenter) gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER_ALWAYS);
|
||||
g_signal_connect_swapped(G_OBJECT(window), "delete_event", G_CALLBACK(hiro_pwindow_close), (gpointer)this);
|
||||
g_signal_connect(G_OBJECT(window), "key_press_event", G_CALLBACK(hiro_pwindow_keydown), (gpointer)this);
|
||||
g_signal_connect(G_OBJECT(window), "key_release_event", G_CALLBACK(hiro_pwindow_keyup), (gpointer)this);
|
||||
|
||||
menucontainer = gtk_vbox_new(false, 0);
|
||||
gtk_container_add(GTK_CONTAINER(window), menucontainer);
|
||||
gtk_widget_show(menucontainer);
|
||||
|
||||
menubar = gtk_menu_bar_new();
|
||||
gtk_box_pack_start(GTK_BOX(menucontainer), menubar, false, false, 0);
|
||||
|
||||
formcontainer = gtk_fixed_new();
|
||||
gtk_widget_set_size_request(formcontainer, width, height);
|
||||
gtk_box_pack_start(GTK_BOX(menucontainer), formcontainer, true, true, 0);
|
||||
gtk_widget_show(formcontainer);
|
||||
|
||||
//GTK+ statusbar background can be transparent, depending upon GTK+ theme
|
||||
//therefore, pack statusbar inside an event box, which always has a background
|
||||
//this allows pWindow::set_background_color() to change the window color,
|
||||
//without affecting the statusbar color
|
||||
statuscontainer = gtk_event_box_new();
|
||||
statusbar = gtk_statusbar_new();
|
||||
gtk_container_add(GTK_CONTAINER(statuscontainer), statusbar);
|
||||
gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(statusbar), false);
|
||||
gtk_box_pack_start(GTK_BOX(menucontainer), statuscontainer, false, false, 0);
|
||||
gtk_widget_show(statuscontainer);
|
||||
|
||||
state.is_fullscreen = false;
|
||||
state.width = width;
|
||||
state.height = height;
|
||||
}
|
||||
|
||||
void pWindow::close() {
|
||||
gtk_widget_destroy(window);
|
||||
}
|
||||
|
||||
void pWindow::move(uint x, uint y) {
|
||||
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_NONE);
|
||||
gtk_window_move(GTK_WINDOW(window), x, y);
|
||||
}
|
||||
|
||||
void pWindow::resize(uint width, uint height) {
|
||||
gtk_widget_set_size_request(formcontainer, width, height);
|
||||
state.width = width;
|
||||
state.height = height;
|
||||
}
|
||||
|
||||
void pWindow::focus() {
|
||||
gtk_window_present(GTK_WINDOW(window));
|
||||
}
|
||||
|
||||
bool pWindow::focused() {
|
||||
return gtk_window_is_active(GTK_WINDOW(window));
|
||||
}
|
||||
|
||||
//gtk_window_(un/)fullscreen() alone does not work well on certain WMs, such as Openbox.
|
||||
//sometimes, the window will not resize (but will move to the top left.)
|
||||
//sometimes, the window decorations will not disappear.
|
||||
//therefore, to be safe, perform some manual window adjustments as well
|
||||
|
||||
void pWindow::fullscreen() {
|
||||
if(state.is_fullscreen == true) return;
|
||||
state.is_fullscreen = true;
|
||||
|
||||
gtk_window_fullscreen(GTK_WINDOW(window));
|
||||
gtk_window_set_decorated(GTK_WINDOW(window), false);
|
||||
gtk_widget_set_size_request(window, gdk_screen_width(), gdk_screen_height());
|
||||
}
|
||||
|
||||
//note that the size of the window is bound to be at least the size of the formcontainer.
|
||||
//this is why the window size is set to -1, -1 below, so that it becomes the minimum
|
||||
//needed to display all of the formcontainer.
|
||||
|
||||
void pWindow::unfullscreen() {
|
||||
if(state.is_fullscreen == false) return;
|
||||
state.is_fullscreen = false;
|
||||
|
||||
gtk_widget_set_size_request(formcontainer, state.width, state.height);
|
||||
gtk_widget_set_size_request(window, -1, -1);
|
||||
gtk_window_set_decorated(GTK_WINDOW(window), true);
|
||||
gtk_window_unfullscreen(GTK_WINDOW(window));
|
||||
}
|
||||
|
||||
//gtk_widget_size_request() on a window immediately after gtk_window_(un/)fullscreen()
|
||||
//is unreliable, as it will usually report the previous window size.
|
||||
//therefore, calculate it manually by using state information.
|
||||
|
||||
uint pWindow::get_width() {
|
||||
if(state.is_fullscreen == false) return state.width;
|
||||
return gdk_screen_width();
|
||||
}
|
||||
|
||||
uint pWindow::get_height() {
|
||||
if(state.is_fullscreen == false) return state.height;
|
||||
uint height = gdk_screen_height();
|
||||
|
||||
//do not include menubar height in client area height
|
||||
if(menu.visible()) {
|
||||
GtkRequisition req;
|
||||
gtk_widget_size_request(menubar, &req);
|
||||
height -= req.height;
|
||||
}
|
||||
|
||||
//do not include statusbar height in client area height
|
||||
if(status.visible()) {
|
||||
GtkRequisition req;
|
||||
gtk_widget_size_request(statusbar, &req);
|
||||
height -= req.height;
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
void pWindow::set_background_color(uint8_t r, uint8_t g, uint8_t b) {
|
||||
GdkColor color;
|
||||
color.pixel = (r << 16) | (g << 8) | b;
|
||||
color.red = (r << 8) | r;
|
||||
color.green = (g << 8) | g;
|
||||
color.blue = (b << 8) | b;
|
||||
gtk_widget_modify_bg(window, GTK_STATE_NORMAL, &color);
|
||||
}
|
||||
|
||||
void pWindow::set_text(const char *text) {
|
||||
gtk_window_set_title(GTK_WINDOW(window), text ? text : "");
|
||||
}
|
||||
|
||||
void pWindow::attach(Window &window, uint x, uint y) {
|
||||
window.p.owner = this;
|
||||
|
||||
//GTK+ does not support attaching a window to another window,
|
||||
//so instead reparent the container from the child window to
|
||||
//the parent window, and reposition the child window's container
|
||||
gtk_widget_hide(window.p.window);
|
||||
gtk_widget_hide(window.p.formcontainer);
|
||||
gtk_widget_reparent(window.p.formcontainer, formcontainer);
|
||||
gtk_fixed_move(GTK_FIXED(formcontainer), window.p.formcontainer, x, y);
|
||||
gtk_widget_show(window.p.formcontainer);
|
||||
}
|
||||
|
||||
void pWindow::attach(MenuGroup &menugroup) {
|
||||
gtk_menu_bar_append(menubar, menugroup.p.item);
|
||||
gtk_widget_show(menubar);
|
||||
}
|
||||
|
||||
void pWindow::attach(FormControl &formcontrol, uint x, uint y) {
|
||||
gtk_fixed_put(GTK_FIXED(formcontainer), formcontrol.p.gtk_handle(), x, y);
|
||||
}
|
||||
|
||||
void pWindow::move(Window &window, uint x, uint y) {
|
||||
gtk_fixed_move(GTK_FIXED(formcontainer), window.p.gtk_handle(), x, y);
|
||||
}
|
||||
|
||||
void pWindow::move(FormControl &formcontrol, uint x, uint y) {
|
||||
gtk_fixed_move(GTK_FIXED(formcontainer), formcontrol.p.gtk_handle(), x, y);
|
||||
}
|
||||
|
||||
/* pWindow -> Menubar */
|
||||
|
||||
void pWindow::Menubar::show(bool state) {
|
||||
p.menu_show(state);
|
||||
}
|
||||
|
||||
void pWindow::Menubar::hide() {
|
||||
p.menu_hide();
|
||||
}
|
||||
|
||||
bool pWindow::Menubar::visible() {
|
||||
return p.menu_visible();
|
||||
}
|
||||
|
||||
pWindow::Menubar::Menubar(pWindow &p_) : p(p_) {
|
||||
}
|
||||
|
||||
/* pWindow -> Statusbar */
|
||||
|
||||
void pWindow::Statusbar::set_text(const char *text) {
|
||||
p.status_set_text(text);
|
||||
}
|
||||
|
||||
void pWindow::Statusbar::show(bool state) {
|
||||
p.status_show(state);
|
||||
}
|
||||
|
||||
void pWindow::Statusbar::hide() {
|
||||
p.status_hide();
|
||||
}
|
||||
|
||||
bool pWindow::Statusbar::visible() {
|
||||
return p.status_visible();
|
||||
}
|
||||
|
||||
pWindow::Statusbar::Statusbar(pWindow &p_) : p(p_) {
|
||||
}
|
||||
|
||||
pWindow::pWindow(Window &self_) : pWidget(self_), self(self_), menu(*this), status(*this) {
|
||||
owner = 0;
|
||||
window = 0;
|
||||
menubar = 0;
|
||||
statusbar = 0;
|
||||
menucontainer = 0;
|
||||
formcontainer = 0;
|
||||
statuscontainer = 0;
|
||||
|
||||
state.is_fullscreen = false;
|
||||
state.width = 0;
|
||||
state.height = 0;
|
||||
}
|
||||
|
||||
/* internal */
|
||||
|
||||
GtkWidget* pWindow::gtk_handle() {
|
||||
return owner ? formcontainer : window;
|
||||
}
|
||||
|
||||
void pWindow::menu_show(bool state) {
|
||||
state ? gtk_widget_show(menubar) : gtk_widget_hide(menubar);
|
||||
}
|
||||
|
||||
void pWindow::menu_hide() {
|
||||
menu_show(false);
|
||||
}
|
||||
|
||||
bool pWindow::menu_visible() {
|
||||
return GTK_WIDGET_VISIBLE(menubar);
|
||||
}
|
||||
|
||||
void pWindow::status_set_text(const char *text) {
|
||||
gtk_statusbar_pop(GTK_STATUSBAR(statusbar), 1);
|
||||
gtk_statusbar_push(GTK_STATUSBAR(statusbar), 1, text ? text : "");
|
||||
}
|
||||
|
||||
void pWindow::status_show(bool state) {
|
||||
state ? gtk_widget_show(statusbar) : gtk_widget_hide(statusbar);
|
||||
}
|
||||
|
||||
void pWindow::status_hide() {
|
||||
status_show(false);
|
||||
}
|
||||
|
||||
bool pWindow::status_visible() {
|
||||
return GTK_WIDGET_VISIBLE(statusbar);
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
class pWindow : public pWidget {
|
||||
public:
|
||||
void create(uint style, uint width, uint height, const char *text = "");
|
||||
void close();
|
||||
void move(uint x, uint y);
|
||||
void resize(uint width, uint height);
|
||||
void focus();
|
||||
bool focused();
|
||||
void fullscreen();
|
||||
void unfullscreen();
|
||||
uint get_width();
|
||||
uint get_height();
|
||||
void set_background_color(uint8_t r, uint8_t g, uint8_t b);
|
||||
void set_text(const char *text = "");
|
||||
void attach(Window &window, uint x, uint y);
|
||||
void attach(MenuGroup &menugroup);
|
||||
void attach(FormControl &formcontrol, uint x, uint y);
|
||||
void move(Window &window, uint x, uint y);
|
||||
void move(FormControl &formcontrol, uint x, uint y);
|
||||
|
||||
class Statusbar {
|
||||
public:
|
||||
void set_text(const char *text = "");
|
||||
void show(bool = true);
|
||||
void hide();
|
||||
bool visible();
|
||||
|
||||
pWindow &p;
|
||||
Statusbar(pWindow&);
|
||||
} status;
|
||||
|
||||
class Menubar {
|
||||
public:
|
||||
void show(bool = true);
|
||||
void hide();
|
||||
bool visible();
|
||||
|
||||
pWindow &p;
|
||||
Menubar(pWindow&);
|
||||
} menu;
|
||||
|
||||
Window &self;
|
||||
pWindow(Window&);
|
||||
|
||||
/* internal */
|
||||
pWindow *owner; //0 = no owner (default)
|
||||
GtkWidget *window;
|
||||
GtkWidget *menubar;
|
||||
GtkWidget *statusbar;
|
||||
GtkWidget *menucontainer;
|
||||
GtkWidget *formcontainer;
|
||||
GtkWidget *statuscontainer;
|
||||
GtkWidget* gtk_handle();
|
||||
struct {
|
||||
bool is_fullscreen;
|
||||
uint width;
|
||||
uint height;
|
||||
} state;
|
||||
|
||||
void menu_show(bool = true);
|
||||
void menu_hide();
|
||||
bool menu_visible();
|
||||
|
||||
void status_set_text(const char *text = "");
|
||||
void status_show(bool = true);
|
||||
void status_hide();
|
||||
bool status_visible();
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
void pButton::create(uint style, uint width, uint height, const char *text) {
|
||||
hwnd = CreateWindow("BUTTON", text ? text : "", WS_CHILD | WS_VISIBLE,
|
||||
0, 0, width, height,
|
||||
phiro().default_hwnd, (HMENU)instance, GetModuleHandle(0), 0);
|
||||
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)this);
|
||||
SendMessage(hwnd, WM_SETFONT, (WPARAM)phiro().default_font, 0);
|
||||
}
|
||||
|
||||
void pButton::set_text(const char *text) {
|
||||
SetWindowText(hwnd, text ? text : "");
|
||||
}
|
||||
|
||||
pButton::pButton(Button &self_) : pFormControl(self_), self(self_) {
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
class pButton : public pFormControl {
|
||||
public:
|
||||
Button &self;
|
||||
void create(uint style, uint width, uint height, const char *text = "");
|
||||
void set_text(const char *text = "");
|
||||
|
||||
pButton(Button&);
|
||||
};
|
||||
@@ -0,0 +1,54 @@
|
||||
void pCanvas::create(uint style, uint width, uint height) {
|
||||
hwnd = CreateWindow("hiro_window", "", WS_CHILD,
|
||||
0, 0, width, height,
|
||||
phiro().default_hwnd, (HMENU)instance, GetModuleHandle(0), 0);
|
||||
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)this);
|
||||
resize(width, height);
|
||||
ShowWindow(hwnd, SW_NORMAL);
|
||||
}
|
||||
|
||||
void pCanvas::redraw() {
|
||||
}
|
||||
|
||||
uint32_t* pCanvas::buffer() {
|
||||
return ibuffer;
|
||||
}
|
||||
|
||||
pCanvas::pCanvas(Canvas &self_) : pFormControl(self_), self(self_) {
|
||||
ibuffer = 0;
|
||||
ipitch = 0;
|
||||
memset(&bmi, 0, sizeof(BITMAPINFO));
|
||||
bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
|
||||
bmi.bmiHeader.biPlanes = 1;
|
||||
bmi.bmiHeader.biBitCount = 32;
|
||||
bmi.bmiHeader.biCompression = BI_RGB;
|
||||
}
|
||||
|
||||
pCanvas::~pCanvas() {
|
||||
if(ibuffer) free(ibuffer);
|
||||
}
|
||||
|
||||
/* internal */
|
||||
|
||||
void pCanvas::blit() {
|
||||
PAINTSTRUCT ps;
|
||||
BeginPaint(hwnd, &ps);
|
||||
SetDIBitsToDevice(ps.hdc, 0, 0, iwidth, iheight, 0, 0, 0, iheight, (void*)ibuffer, &bmi, DIB_RGB_COLORS);
|
||||
EndPaint(hwnd, &ps);
|
||||
}
|
||||
|
||||
void pCanvas::resize(uint width, uint height) {
|
||||
if(ibuffer) free(ibuffer);
|
||||
|
||||
ipitch = width * sizeof(uint32_t);
|
||||
iwidth = width;
|
||||
iheight = height;
|
||||
ibuffer = (uint32_t*)malloc(ipitch * height);
|
||||
memset(ibuffer, 0, ipitch * height);
|
||||
|
||||
bmi.bmiHeader.biWidth = width;
|
||||
bmi.bmiHeader.biHeight = -height; //use negative height to tell GDI not to flip bitmap vertically
|
||||
bmi.bmiHeader.biSizeImage = ipitch * height;
|
||||
|
||||
pFormControl::resize(width, height);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
class pCanvas : public pFormControl {
|
||||
public:
|
||||
void create(uint style, uint width, uint height);
|
||||
void redraw();
|
||||
uint32_t* buffer();
|
||||
|
||||
Canvas &self;
|
||||
pCanvas(Canvas&);
|
||||
~pCanvas();
|
||||
|
||||
/* internal */
|
||||
BITMAPINFO bmi;
|
||||
uint32_t *ibuffer;
|
||||
uint ipitch, iwidth, iheight;
|
||||
void blit();
|
||||
void resize(uint width, uint height);
|
||||
};
|
||||
@@ -0,0 +1,29 @@
|
||||
void pCheckbox::create(uint style, uint width, uint height, const char *text) {
|
||||
hwnd = CreateWindow("BUTTON", text ? text : "", WS_CHILD | WS_VISIBLE | BS_CHECKBOX,
|
||||
0, 0, width, height,
|
||||
phiro().default_hwnd, (HMENU)instance, GetModuleHandle(0), 0);
|
||||
SendMessage(hwnd, WM_SETFONT, (WPARAM)phiro().default_font, 0);
|
||||
}
|
||||
|
||||
void pCheckbox::set_text(const char *text) {
|
||||
SetWindowText(hwnd, text ? text : "");
|
||||
}
|
||||
|
||||
void pCheckbox::check(bool state) {
|
||||
bool prev = checked();
|
||||
SendMessage(hwnd, BM_SETCHECK, (WPARAM)(state ? TRUE : FALSE), 0);
|
||||
if(prev != state) {
|
||||
if(self.on_tick) self.on_tick(Event(Event::Tick, state, &self));
|
||||
}
|
||||
}
|
||||
|
||||
void pCheckbox::uncheck() {
|
||||
check(false);
|
||||
}
|
||||
|
||||
bool pCheckbox::checked() {
|
||||
return SendMessage(hwnd, BM_GETCHECK, 0, 0);
|
||||
}
|
||||
|
||||
pCheckbox::pCheckbox(Checkbox &self_) : pFormControl(self_), self(self_) {
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
class pCheckbox : public pFormControl {
|
||||
public:
|
||||
void create(uint style, uint width, uint height, const char *text = "");
|
||||
void set_text(const char *text = "");
|
||||
void check(bool state = true);
|
||||
void uncheck();
|
||||
bool checked();
|
||||
|
||||
Checkbox &self;
|
||||
pCheckbox(Checkbox&);
|
||||
};
|
||||
@@ -0,0 +1,28 @@
|
||||
void pCombobox::create(uint style, uint width, uint height, const char *text) {
|
||||
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, "COMBOBOX", "",
|
||||
WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | CBS_HASSTRINGS,
|
||||
0, 0, width, 200,
|
||||
phiro().default_hwnd, (HMENU)instance, GetModuleHandle(0), 0);
|
||||
SendMessage(hwnd, WM_SETFONT, (WPARAM)phiro().default_font, 0);
|
||||
}
|
||||
|
||||
void pCombobox::add_item(const char *text) {
|
||||
SendMessage(hwnd, CB_ADDSTRING, 0, (LPARAM)text);
|
||||
if(SendMessage(hwnd, CB_GETCOUNT, 0, 0) == 1) set_selection(0);
|
||||
}
|
||||
|
||||
int pCombobox::get_selection() {
|
||||
return SendMessage(hwnd, CB_GETCURSEL, 0, 0);
|
||||
}
|
||||
|
||||
void pCombobox::set_selection(int index) {
|
||||
SendMessage(hwnd, CB_SETCURSEL, combobox_selection = index, 0);
|
||||
}
|
||||
|
||||
void pCombobox::reset() {
|
||||
SendMessage(hwnd, CB_RESETCONTENT, 0, 0);
|
||||
}
|
||||
|
||||
pCombobox::pCombobox(Combobox &self_) : pFormControl(self_), self(self_) {
|
||||
combobox_selection = 0;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
class pCombobox : public pFormControl {
|
||||
public:
|
||||
Combobox &self;
|
||||
void create(uint style, uint width, uint height, const char *text = "");
|
||||
void add_item(const char *text);
|
||||
int get_selection();
|
||||
void set_selection(int index);
|
||||
void reset();
|
||||
|
||||
pCombobox(Combobox&);
|
||||
|
||||
/* internal */
|
||||
int combobox_selection;
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
void pEditbox::create(uint style, uint width, uint height, const char *text) {
|
||||
bool multiline = style & Editbox::Multiline;
|
||||
bool readonly = style & Editbox::Readonly;
|
||||
uint vscroll = (style & Editbox::VerticalScrollAlways) ? WS_VSCROLL :
|
||||
(style & Editbox::VerticalScrollNever) ? 0 :
|
||||
ES_AUTOVSCROLL;
|
||||
uint hscroll = (style & Editbox::HorizontalScrollAlways) ? WS_HSCROLL :
|
||||
(style & Editbox::HorizontalScrollNever) ? 0 :
|
||||
ES_AUTOHSCROLL;
|
||||
|
||||
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", "",
|
||||
WS_CHILD | WS_VISIBLE | vscroll | hscroll |
|
||||
(multiline == true ? ES_MULTILINE : 0) |
|
||||
(readonly == true ? ES_READONLY : 0),
|
||||
0, 0, width, height,
|
||||
phiro().default_hwnd, (HMENU)instance, GetModuleHandle(0), 0);
|
||||
SendMessage(hwnd, WM_SETFONT, (WPARAM)phiro().default_font, 0);
|
||||
set_text(text);
|
||||
}
|
||||
|
||||
void pEditbox::set_text(const char *text) {
|
||||
string temp = text ? text : "";
|
||||
replace(temp, "\r", "");
|
||||
replace(temp, "\n", "\r\n");
|
||||
SetWindowText(hwnd, temp);
|
||||
}
|
||||
|
||||
uint pEditbox::get_text(char *text, uint length) {
|
||||
GetWindowText(hwnd, text, length);
|
||||
string temp = text;
|
||||
replace(temp, "\r", "");
|
||||
strcpy(text, temp);
|
||||
return strlen(text);
|
||||
}
|
||||
|
||||
pEditbox::pEditbox(Editbox &self_) : pFormControl(self_), self(self_) {
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
class pEditbox : public pFormControl {
|
||||
public:
|
||||
Editbox &self;
|
||||
void create(uint style, uint width, uint height, const char *text = "");
|
||||
uint get_text(char *text, uint length = -1U);
|
||||
void set_text(const char *text = "");
|
||||
|
||||
pEditbox(Editbox&);
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
void pFormControl::resize(uint width, uint height) {
|
||||
SetWindowPos(hwnd, 0, 0, 0, width, height, SWP_NOZORDER | SWP_NOMOVE);
|
||||
}
|
||||
|
||||
void pFormControl::focus() {
|
||||
SetFocus(hwnd);
|
||||
}
|
||||
|
||||
bool pFormControl::focused() {
|
||||
return true; //fixme
|
||||
}
|
||||
|
||||
void pFormControl::enable(bool state) {
|
||||
EnableWindow(hwnd, state);
|
||||
}
|
||||
|
||||
void pFormControl::disable() {
|
||||
enable(false);
|
||||
}
|
||||
|
||||
bool pFormControl::enabled() {
|
||||
return !(GetWindowLong(hwnd, GWL_STYLE) & WS_DISABLED);
|
||||
}
|
||||
|
||||
uintptr_t pFormControl::handle() {
|
||||
return (uintptr_t)hwnd;
|
||||
}
|
||||
|
||||
pFormControl::pFormControl(FormControl &self_) : pWidget(self_), self(self_) {
|
||||
hwnd = 0;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
class pFormControl : public pWidget {
|
||||
public:
|
||||
virtual void resize(uint width, uint height);
|
||||
void focus();
|
||||
bool focused();
|
||||
void enable(bool = true);
|
||||
void disable();
|
||||
bool enabled();
|
||||
uintptr_t handle();
|
||||
|
||||
FormControl &self;
|
||||
pFormControl(FormControl&);
|
||||
|
||||
/* internal */
|
||||
HWND hwnd;
|
||||
};
|
||||
@@ -0,0 +1,13 @@
|
||||
void pFrame::create(uint style, uint width, uint height, const char *text) {
|
||||
hwnd = CreateWindow("BUTTON", text ? text : "", WS_CHILD | WS_VISIBLE | BS_GROUPBOX,
|
||||
0, 0, width, height,
|
||||
phiro().default_hwnd, (HMENU)instance, GetModuleHandle(0), 0);
|
||||
SendMessage(hwnd, WM_SETFONT, (WPARAM)phiro().default_font, 0);
|
||||
}
|
||||
|
||||
void pFrame::set_text(const char *text) {
|
||||
SetWindowText(hwnd, text ? text : "");
|
||||
}
|
||||
|
||||
pFrame::pFrame(Frame &self_) : pFormControl(self_), self(self_) {
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
class pFrame : public pFormControl {
|
||||
public:
|
||||
Frame &self;
|
||||
void create(uint style, uint width, uint height, const char *text = "");
|
||||
void set_text(const char *text = "");
|
||||
|
||||
pFrame(Frame&);
|
||||
};
|
||||
@@ -0,0 +1,336 @@
|
||||
#include "hiro.h"
|
||||
|
||||
#include <nall/algorithm.hpp>
|
||||
using nall::min;
|
||||
using nall::max;
|
||||
|
||||
namespace libhiro {
|
||||
|
||||
LRESULT CALLBACK phiro_wndproc(HWND, UINT, WPARAM, LPARAM);
|
||||
|
||||
#include "keymap.cpp"
|
||||
#include "widget.cpp"
|
||||
#include "window.cpp"
|
||||
#include "menucontrol.cpp"
|
||||
#include "menugroup.cpp"
|
||||
#include "menuitem.cpp"
|
||||
#include "menucheckitem.cpp"
|
||||
#include "menuradioitem.cpp"
|
||||
#include "menuseparator.cpp"
|
||||
#include "formcontrol.cpp"
|
||||
#include "frame.cpp"
|
||||
#include "canvas.cpp"
|
||||
#include "label.cpp"
|
||||
#include "button.cpp"
|
||||
#include "checkbox.cpp"
|
||||
#include "radiobox.cpp"
|
||||
#include "editbox.cpp"
|
||||
#include "listbox.cpp"
|
||||
#include "combobox.cpp"
|
||||
#include "progressbar.cpp"
|
||||
#include "slider.cpp"
|
||||
|
||||
void pHiro::init() {
|
||||
WNDCLASS wc;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW);
|
||||
wc.hCursor = LoadCursor(0, IDC_ARROW);
|
||||
wc.hIcon = LoadIcon(0, IDI_APPLICATION);
|
||||
wc.hInstance = GetModuleHandle(0);
|
||||
wc.lpfnWndProc = phiro_wndproc;
|
||||
wc.lpszClassName = "hiro_window";
|
||||
wc.lpszMenuName = 0;
|
||||
wc.style = CS_HREDRAW | CS_VREDRAW;
|
||||
RegisterClass(&wc);
|
||||
|
||||
InitCommonControls();
|
||||
default_hwnd = CreateWindow("hiro_window", "", WS_POPUP, 0, 0, 640, 480, 0, 0, GetModuleHandle(0), 0);
|
||||
default_font = create_font("Tahoma", 9);
|
||||
black_brush = CreateSolidBrush(RGB(0, 0, 0));
|
||||
}
|
||||
|
||||
void pHiro::term() {
|
||||
DeleteObject(black_brush);
|
||||
}
|
||||
|
||||
bool pHiro::run() {
|
||||
MSG msg;
|
||||
if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
return pending();
|
||||
}
|
||||
|
||||
bool pHiro::pending() {
|
||||
MSG msg;
|
||||
return PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE);
|
||||
}
|
||||
|
||||
bool pHiro::file_load(Window *focus, char *filename, const char *filter, const char *path) {
|
||||
string dir, f;
|
||||
strcpy(dir, path ? path : "");
|
||||
replace(dir, "/", "\\");
|
||||
|
||||
lstring type, part;
|
||||
strcpy(f, "");
|
||||
split(type, "|", filter);
|
||||
for(int i = 0; i < count(type); i++) {
|
||||
split(part, ";", type[i]);
|
||||
if(count(part) != 2)continue;
|
||||
|
||||
strcat(f, part[0]);
|
||||
strcat(f, " (");
|
||||
strcat(f, part[1]);
|
||||
strcat(f, ")|");
|
||||
replace(part[1], ",", ";");
|
||||
strcat(f, part[1]);
|
||||
strcat(f, "|");
|
||||
}
|
||||
|
||||
char *pf = f();
|
||||
for(int i = strlen(pf) - 1; i >= 0; i--) {
|
||||
if(pf[i] == '|') pf[i] = '\0';
|
||||
}
|
||||
|
||||
OPENFILENAME ofn;
|
||||
strcpy(filename, "");
|
||||
memset(&ofn, 0, sizeof(ofn));
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.hwndOwner = focus ? focus->p.hwnd : 0;
|
||||
ofn.lpstrFilter = pf;
|
||||
ofn.lpstrInitialDir = dir;
|
||||
ofn.lpstrFile = filename;
|
||||
ofn.nMaxFile = MAX_PATH;
|
||||
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST;
|
||||
ofn.lpstrDefExt = "";
|
||||
|
||||
return GetOpenFileName(&ofn);
|
||||
}
|
||||
|
||||
bool pHiro::file_save(Window *focus, char *filename, const char *filter, const char *path) {
|
||||
string dir, f;
|
||||
strcpy(dir, path ? path : "");
|
||||
replace(dir, "/", "\\");
|
||||
|
||||
lstring type, part;
|
||||
strcpy(f, "");
|
||||
split(type, "|", filter);
|
||||
for(int i = 0; i < count(type); i++) {
|
||||
split(part, ";", type[i]);
|
||||
if(count(part) != 2)continue;
|
||||
|
||||
strcat(f, part[0]);
|
||||
strcat(f, " (");
|
||||
strcat(f, part[1]);
|
||||
strcat(f, ")|");
|
||||
replace(part[1], ",", ";");
|
||||
strcat(f, part[1]);
|
||||
strcat(f, "|");
|
||||
}
|
||||
|
||||
char *pf = f();
|
||||
for(int i = strlen(pf) - 1; i >= 0; i--) {
|
||||
if(pf[i] == '|') pf[i] = '\0';
|
||||
}
|
||||
|
||||
OPENFILENAME ofn;
|
||||
strcpy(filename, "");
|
||||
memset(&ofn, 0, sizeof(ofn));
|
||||
ofn.lStructSize = sizeof(ofn);
|
||||
ofn.hwndOwner = focus ? focus->p.hwnd : 0;
|
||||
ofn.lpstrFilter = pf;
|
||||
ofn.lpstrInitialDir = dir;
|
||||
ofn.lpstrFile = filename;
|
||||
ofn.nMaxFile = MAX_PATH;
|
||||
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST;
|
||||
ofn.lpstrDefExt = "";
|
||||
|
||||
return GetSaveFileName(&ofn);
|
||||
}
|
||||
|
||||
uint pHiro::screen_width() {
|
||||
return GetSystemMetrics(SM_CXSCREEN);
|
||||
}
|
||||
|
||||
uint pHiro::screen_height() {
|
||||
return GetSystemMetrics(SM_CYSCREEN);
|
||||
}
|
||||
|
||||
pHiro& pHiro::handle() {
|
||||
return hiro().p;
|
||||
}
|
||||
|
||||
pHiro::pHiro(Hiro &self_) : self(self_) {
|
||||
}
|
||||
|
||||
pHiro& phiro() {
|
||||
return pHiro::handle();
|
||||
}
|
||||
|
||||
/* internal */
|
||||
|
||||
HFONT pHiro::create_font(const char *name, uint size) {
|
||||
HDC hdc = GetDC(0);
|
||||
HFONT font = CreateFont(-MulDiv(size, GetDeviceCaps(hdc, LOGPIXELSY), 72),
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, name);
|
||||
ReleaseDC(0, hdc);
|
||||
return font;
|
||||
}
|
||||
|
||||
Widget* pHiro::get_widget(uint instance) {
|
||||
Widget *widget = 0;
|
||||
for(uint i = 0; i < widget_list.size(); i++) {
|
||||
if(widget_list[i]->p.instance != instance) continue;
|
||||
widget = widget_list[i];
|
||||
break;
|
||||
}
|
||||
return widget;
|
||||
}
|
||||
|
||||
LRESULT CALLBACK phiro_wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
return phiro().wndproc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
LRESULT pHiro::wndproc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) {
|
||||
pWidget *p = (pWidget*)GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
||||
|
||||
switch(msg) {
|
||||
case WM_SYSCOMMAND: {
|
||||
switch(wparam) {
|
||||
//TODO: write hiro API to allow this to be toggled.
|
||||
//for now, screensaver and monitorpower events are disabled always.
|
||||
case SC_SCREENSAVE:
|
||||
case SC_MONITORPOWER:
|
||||
return FALSE;
|
||||
}
|
||||
} break;
|
||||
|
||||
case WM_SIZE: {
|
||||
if(!p || p->self.type != Widget::WindowType) break;
|
||||
SendMessage(((pWindow*)p)->hstatus, WM_SIZE, 0, 0); //the control itself auto-sizes after receiving WM_SIZE
|
||||
} break;
|
||||
|
||||
case WM_CLOSE: {
|
||||
if(!p || p->self.type != Widget::WindowType) break;
|
||||
Window &w = ((pWindow*)p)->self;
|
||||
if(w.on_close) return (bool)w.on_close(Event(Event::Close, 0, &w));
|
||||
return TRUE; //true = destroy window
|
||||
} break;
|
||||
|
||||
case WM_ENTERMENULOOP: {
|
||||
if(!p || p->self.type != Widget::WindowType) break;
|
||||
Window &w = ((pWindow*)p)->self;
|
||||
if(w.on_block) w.on_block(Event(Event::Block, 0, &w));
|
||||
} break;
|
||||
|
||||
case WM_KEYDOWN: {
|
||||
if(!p || p->self.type != Widget::WindowType) break;
|
||||
Window &w = ((pWindow*)p)->self;
|
||||
if(w.on_keydown) w.on_keydown(Event(Event::KeyDown, translate_key(wparam), &w));
|
||||
} break;
|
||||
|
||||
case WM_KEYUP: {
|
||||
if(!p || p->self.type != Widget::WindowType) break;
|
||||
Window &w = ((pWindow*)p)->self;
|
||||
if(w.on_keyup) w.on_keyup(Event(Event::KeyUp, translate_key(wparam), &w));
|
||||
} break;
|
||||
|
||||
case WM_ERASEBKGND: {
|
||||
if(!p) break;
|
||||
HBRUSH brush = 0;
|
||||
if(p->self.type == Widget::WindowType) brush = ((pWindow*)p)->background;
|
||||
if(p->self.type == Widget::CanvasType) brush = phiro().black_brush;
|
||||
if(!brush) break;
|
||||
RECT rc;
|
||||
GetClientRect(hwnd, &rc);
|
||||
PAINTSTRUCT ps;
|
||||
BeginPaint(hwnd, &ps);
|
||||
FillRect(ps.hdc, &rc, brush);
|
||||
EndPaint(hwnd, &ps);
|
||||
return TRUE;
|
||||
} break;
|
||||
|
||||
case WM_PAINT: {
|
||||
if(p && p->self.type == Widget::CanvasType) ((pCanvas*)p)->blit();
|
||||
} break;
|
||||
|
||||
case WM_COMMAND: {
|
||||
Widget *widget = get_widget(LOWORD(wparam));
|
||||
if(!widget) break;
|
||||
|
||||
switch(widget->type) {
|
||||
case Widget::MenuItemType: {
|
||||
MenuItem &w = (MenuItem&)*widget;
|
||||
if(w.on_tick) w.on_tick(Event(Event::Tick, 0, &w));
|
||||
} break;
|
||||
case Widget::MenuCheckItemType: {
|
||||
MenuCheckItem &w = (MenuCheckItem&)*widget;
|
||||
w.check(!w.checked()); //invert check state
|
||||
} break;
|
||||
case Widget::MenuRadioItemType: {
|
||||
MenuRadioItem &w = (MenuRadioItem&)*widget;
|
||||
w.check();
|
||||
} break;
|
||||
case Widget::ButtonType: {
|
||||
Button &w = (Button&)*widget;
|
||||
if(w.on_tick) w.on_tick(Event(Event::Tick, 0, &w));
|
||||
} break;
|
||||
case Widget::CheckboxType: {
|
||||
Checkbox &w = (Checkbox&)*widget;
|
||||
w.check(!w.checked()); //invert check state
|
||||
} break;
|
||||
case Widget::RadioboxType: {
|
||||
Radiobox &w = (Radiobox&)*widget;
|
||||
w.check();
|
||||
} break;
|
||||
case Widget::ComboboxType: {
|
||||
Combobox &combobox = (Combobox&)*widget;
|
||||
if(HIWORD(wparam) == CBN_SELCHANGE) {
|
||||
if(combobox.p.combobox_selection == combobox.get_selection()) break;
|
||||
if(combobox.on_change) combobox.on_change(Event(Event::Change, combobox.p.combobox_selection = combobox.get_selection(), &combobox));
|
||||
}
|
||||
} break;
|
||||
}
|
||||
} break;
|
||||
|
||||
case WM_HSCROLL:
|
||||
case WM_VSCROLL: {
|
||||
Widget *widget = get_widget(GetDlgCtrlID((HWND)lparam));
|
||||
if(!widget) break;
|
||||
|
||||
switch(widget->type) {
|
||||
case Widget::SliderType: {
|
||||
Slider &slider = (Slider&)*widget;
|
||||
if(slider.p.slider_position == slider.get_position()) break;
|
||||
if(slider.on_change) slider.on_change(Event(Event::Change, slider.p.slider_position = slider.get_position(), &slider));
|
||||
} break;
|
||||
}
|
||||
} break;
|
||||
|
||||
case WM_NOTIFY: {
|
||||
Widget *widget = get_widget(LOWORD(wparam));
|
||||
if(!widget) break;
|
||||
|
||||
switch(widget->type) {
|
||||
case Widget::ListboxType: {
|
||||
Listbox &listbox = (Listbox&)*widget;
|
||||
if(((LPNMHDR)lparam)->code == LVN_ITEMCHANGED
|
||||
&& ((LPNMLISTVIEW)lparam)->uChanged & LVIF_STATE
|
||||
&& ListView_GetItemState(listbox.p.hwnd, ((LPNMLISTVIEW)lparam)->iItem, LVIS_FOCUSED)
|
||||
&& ListView_GetItemState(listbox.p.hwnd, ((LPNMLISTVIEW)lparam)->iItem, LVIS_SELECTED)
|
||||
) {
|
||||
if(listbox.on_change) listbox.on_change(Event(Event::Change, listbox.get_selection(), &listbox));
|
||||
} else if(((LPNMHDR)lparam)->code == LVN_ITEMACTIVATE) {
|
||||
if(listbox.on_activate) listbox.on_activate(Event(Event::Activate, listbox.get_selection(), &listbox));
|
||||
}
|
||||
} break;
|
||||
}
|
||||
} break;
|
||||
}
|
||||
|
||||
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
} //namespace libhiro
|
||||
@@ -0,0 +1,73 @@
|
||||
#ifndef HIRO_WIN_H
|
||||
#define HIRO_WIN_H
|
||||
|
||||
#undef WINVER
|
||||
#undef _WIN32_WINNT
|
||||
#undef _WIN32_IE
|
||||
#undef NOMINMAX
|
||||
|
||||
#define WINVER 0x0501
|
||||
#define _WIN32_WINNT 0x0501
|
||||
#define _WIN32_IE 0x0600
|
||||
#define NOMINMAX
|
||||
|
||||
#include <windows.h>
|
||||
#include <commctrl.h>
|
||||
|
||||
namespace libhiro {
|
||||
|
||||
#include "widget.h"
|
||||
#include "window.h"
|
||||
#include "menucontrol.h"
|
||||
#include "menugroup.h"
|
||||
#include "menuitem.h"
|
||||
#include "menucheckitem.h"
|
||||
#include "menuradioitem.h"
|
||||
#include "menuseparator.h"
|
||||
#include "formcontrol.h"
|
||||
#include "frame.h"
|
||||
#include "canvas.h"
|
||||
#include "label.h"
|
||||
#include "button.h"
|
||||
#include "checkbox.h"
|
||||
#include "radiobox.h"
|
||||
#include "editbox.h"
|
||||
#include "listbox.h"
|
||||
#include "combobox.h"
|
||||
#include "progressbar.h"
|
||||
#include "slider.h"
|
||||
|
||||
class pHiro {
|
||||
public:
|
||||
Hiro &self;
|
||||
void init();
|
||||
void term();
|
||||
bool run();
|
||||
bool pending();
|
||||
|
||||
bool file_load(Window *focus, char *filename, const char *filter, const char *path);
|
||||
bool file_save(Window *focus, char *filename, const char *filter, const char *path);
|
||||
|
||||
uint screen_width();
|
||||
uint screen_height();
|
||||
|
||||
static pHiro& handle();
|
||||
pHiro(Hiro&);
|
||||
|
||||
/* internal */
|
||||
HWND default_hwnd; //default parent window for all windowless controls
|
||||
HFONT default_font; //default font for all controls
|
||||
HBRUSH black_brush; //used for Canvas background
|
||||
HFONT create_font(const char *name, uint size);
|
||||
|
||||
array<Widget*> widget_list;
|
||||
Widget* get_widget(uint instance);
|
||||
LRESULT wndproc(HWND, UINT, WPARAM, LPARAM);
|
||||
uint16_t translate_key(uint key);
|
||||
};
|
||||
|
||||
pHiro& phiro();
|
||||
|
||||
} //namsepace libhiro
|
||||
|
||||
#endif //ifndef HIRO_WIN_H
|
||||
@@ -0,0 +1,67 @@
|
||||
uint16_t pHiro::translate_key(uint key) {
|
||||
switch(key) {
|
||||
case VK_ESCAPE: return keyboard::escape;
|
||||
|
||||
case VK_F1: return keyboard::f1;
|
||||
case VK_F2: return keyboard::f2;
|
||||
case VK_F3: return keyboard::f3;
|
||||
case VK_F4: return keyboard::f4;
|
||||
case VK_F5: return keyboard::f5;
|
||||
case VK_F6: return keyboard::f6;
|
||||
case VK_F7: return keyboard::f7;
|
||||
case VK_F8: return keyboard::f8;
|
||||
case VK_F9: return keyboard::f9;
|
||||
case VK_F10: return keyboard::f10;
|
||||
case VK_F11: return keyboard::f11;
|
||||
case VK_F12: return keyboard::f12;
|
||||
|
||||
case VK_TAB: return keyboard::tab;
|
||||
case VK_RETURN: return keyboard::return_;
|
||||
case VK_SPACE: return keyboard::spacebar;
|
||||
|
||||
case '0': return keyboard::num_0;
|
||||
case '1': return keyboard::num_1;
|
||||
case '2': return keyboard::num_2;
|
||||
case '3': return keyboard::num_3;
|
||||
case '4': return keyboard::num_4;
|
||||
case '5': return keyboard::num_5;
|
||||
case '6': return keyboard::num_6;
|
||||
case '7': return keyboard::num_7;
|
||||
case '8': return keyboard::num_8;
|
||||
case '9': return keyboard::num_9;
|
||||
|
||||
case 'A': return keyboard::a;
|
||||
case 'B': return keyboard::b;
|
||||
case 'C': return keyboard::c;
|
||||
case 'D': return keyboard::d;
|
||||
case 'E': return keyboard::e;
|
||||
case 'F': return keyboard::f;
|
||||
case 'G': return keyboard::g;
|
||||
case 'H': return keyboard::h;
|
||||
case 'I': return keyboard::i;
|
||||
case 'J': return keyboard::j;
|
||||
case 'K': return keyboard::k;
|
||||
case 'L': return keyboard::l;
|
||||
case 'M': return keyboard::m;
|
||||
case 'N': return keyboard::n;
|
||||
case 'O': return keyboard::o;
|
||||
case 'P': return keyboard::p;
|
||||
case 'Q': return keyboard::q;
|
||||
case 'R': return keyboard::r;
|
||||
case 'S': return keyboard::s;
|
||||
case 'T': return keyboard::t;
|
||||
case 'U': return keyboard::u;
|
||||
case 'V': return keyboard::v;
|
||||
case 'W': return keyboard::w;
|
||||
case 'X': return keyboard::x;
|
||||
case 'Y': return keyboard::y;
|
||||
case 'Z': return keyboard::z;
|
||||
|
||||
case VK_UP: return keyboard::up;
|
||||
case VK_DOWN: return keyboard::down;
|
||||
case VK_LEFT: return keyboard::left;
|
||||
case VK_RIGHT: return keyboard::right;
|
||||
}
|
||||
|
||||
return keyboard::none;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
void pLabel::create(uint style, uint width, uint height, const char *text) {
|
||||
hwnd = CreateWindow("STATIC", text ? text : "", WS_CHILD | WS_VISIBLE,
|
||||
0, 0, width, height,
|
||||
phiro().default_hwnd, (HMENU)instance, GetModuleHandle(0), 0);
|
||||
SendMessage(hwnd, WM_SETFONT, (WPARAM)phiro().default_font, 0);
|
||||
}
|
||||
|
||||
void pLabel::set_text(const char *text) {
|
||||
SetWindowText(hwnd, text ? text : "");
|
||||
}
|
||||
|
||||
pLabel::pLabel(Label &self_) : pFormControl(self_), self(self_) {
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
class pLabel : public pFormControl {
|
||||
public:
|
||||
Label &self;
|
||||
void create(uint style, uint width, uint height, const char *text = "");
|
||||
void set_text(const char *text = "");
|
||||
|
||||
pLabel(Label&);
|
||||
};
|
||||
@@ -0,0 +1,92 @@
|
||||
void pListbox::create(uint style, uint width, uint height, const char *columns, const char *text) {
|
||||
bool header = style & Listbox::Header;
|
||||
uint hscroll = (style & Listbox::HorizontalScrollAlways) ? WS_HSCROLL :
|
||||
(style & Listbox::HorizontalScrollNever) ? 0 :
|
||||
0;
|
||||
uint vscroll = (style & Listbox::VerticalScrollAlways) ? WS_VSCROLL :
|
||||
(style & Listbox::VerticalScrollNever) ? 0 :
|
||||
0;
|
||||
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, "",
|
||||
WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | vscroll | hscroll |
|
||||
(header ? 0 : LVS_NOCOLUMNHEADER),
|
||||
0, 0, width, height,
|
||||
phiro().default_hwnd, (HMENU)instance, GetModuleHandle(0), 0);
|
||||
SendMessage(hwnd, WM_SETFONT, (WPARAM)phiro().default_font, 0);
|
||||
ListView_SetExtendedListViewStyle(hwnd, LVS_EX_FULLROWSELECT);
|
||||
|
||||
lstring list;
|
||||
split(list, "\t", columns ? columns : "");
|
||||
column_count = count(list);
|
||||
for(uint i = 0; i < count(list); i++) {
|
||||
LVCOLUMN column;
|
||||
column.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM;
|
||||
column.fmt = LVCFMT_LEFT;
|
||||
column.iSubItem = count(list);
|
||||
column.pszText = (LPSTR)list[i]();
|
||||
ListView_InsertColumn(hwnd, i, &column);
|
||||
}
|
||||
|
||||
if(text && *text) {
|
||||
split(list, "\n", text);
|
||||
for(uint i = 0; i < count(list); i++) add_item(list[i]);
|
||||
}
|
||||
autosize_columns();
|
||||
}
|
||||
|
||||
void pListbox::autosize_columns() {
|
||||
for(uint i = 0; i < column_count; i++) {
|
||||
ListView_SetColumnWidth(hwnd, i, LVSCW_AUTOSIZE_USEHEADER);
|
||||
}
|
||||
}
|
||||
|
||||
void pListbox::set_column_width(uint column, uint width) {
|
||||
ListView_SetColumnWidth(hwnd, column, width);
|
||||
}
|
||||
|
||||
void pListbox::add_item(const char *text) {
|
||||
lstring list;
|
||||
split(list, "\t", text ? text : "");
|
||||
LVITEM item;
|
||||
uint pos = ListView_GetItemCount(hwnd);
|
||||
item.mask = LVIF_TEXT;
|
||||
item.iItem = pos;
|
||||
item.iSubItem = 0;
|
||||
item.pszText = (LPSTR)list[0]();
|
||||
ListView_InsertItem(hwnd, &item);
|
||||
|
||||
for(uint i = 1; i < count(list); i++) {
|
||||
ListView_SetItemText(hwnd, pos, i, (LPSTR)list[i]());
|
||||
}
|
||||
}
|
||||
|
||||
void pListbox::set_item(uint index, const char *text) {
|
||||
lstring list;
|
||||
split(list, "\t", text ? text : "");
|
||||
for(uint i = 0; i < count(list); i++) {
|
||||
ListView_SetItemText(hwnd, index, i, list[i]());
|
||||
}
|
||||
}
|
||||
|
||||
int pListbox::get_selection() {
|
||||
uint count = ListView_GetItemCount(hwnd);
|
||||
for(uint i = 0; i < count; i++) {
|
||||
if(ListView_GetItemState(hwnd, i, LVIS_SELECTED)) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void pListbox::set_selection(int index) {
|
||||
uint count = ListView_GetItemCount(hwnd);
|
||||
for(uint i = 0; i < count; i++) {
|
||||
ListView_SetItemState(hwnd, i, LVIS_FOCUSED, (i == index) ? LVIS_FOCUSED : 0);
|
||||
ListView_SetItemState(hwnd, i, LVIS_SELECTED, (i == index) ? LVIS_SELECTED : 0);
|
||||
}
|
||||
}
|
||||
|
||||
void pListbox::reset() {
|
||||
ListView_DeleteAllItems(hwnd);
|
||||
}
|
||||
|
||||
pListbox::pListbox(Listbox &self_) : pFormControl(self_), self(self_) {
|
||||
column_count = 0;
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
class pListbox : public pFormControl {
|
||||
public:
|
||||
Listbox &self;
|
||||
void create(uint style, uint width, uint height, const char *columns = "", const char *text = "");
|
||||
void autosize_columns();
|
||||
void set_column_width(uint column, uint width);
|
||||
void add_item(const char *text);
|
||||
void set_item(uint index, const char *text);
|
||||
int get_selection();
|
||||
void set_selection(int index);
|
||||
void reset();
|
||||
|
||||
pListbox(Listbox&);
|
||||
|
||||
/* internal */
|
||||
uint column_count;
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
void pMenuCheckItem::create(const char *text_) {
|
||||
text = strdup(text_);
|
||||
}
|
||||
|
||||
void pMenuCheckItem::check(bool state) {
|
||||
bool prev = checked();
|
||||
CheckMenuItem(parent, instance, state ? MF_CHECKED : MF_UNCHECKED);
|
||||
if(prev != state) {
|
||||
if(self.on_tick) self.on_tick(Event(Event::Tick, state, &self));
|
||||
}
|
||||
}
|
||||
|
||||
void pMenuCheckItem::uncheck() {
|
||||
check(false);
|
||||
}
|
||||
|
||||
bool pMenuCheckItem::checked() {
|
||||
MENUITEMINFO info;
|
||||
memset(&info, 0, sizeof info);
|
||||
info.cbSize = sizeof info;
|
||||
info.fMask = MIIM_STATE;
|
||||
GetMenuItemInfo(parent, instance, false, &info);
|
||||
return info.fState & MFS_CHECKED;
|
||||
}
|
||||
|
||||
pMenuCheckItem::pMenuCheckItem(MenuCheckItem &self_) : pMenuControl(self_), self(self_) {
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
class pMenuCheckItem : public pMenuControl {
|
||||
public:
|
||||
void create(const char *text = "");
|
||||
void check(bool state = true);
|
||||
void uncheck();
|
||||
bool checked();
|
||||
|
||||
MenuCheckItem &self;
|
||||
pMenuCheckItem(MenuCheckItem&);
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
void pMenuControl::enable(bool state) {
|
||||
EnableMenuItem(parent, instance, MF_BYCOMMAND | (state ? MF_ENABLED : MF_GRAYED));
|
||||
}
|
||||
|
||||
void pMenuControl::disable() {
|
||||
enable(false);
|
||||
}
|
||||
|
||||
bool pMenuControl::enabled() {
|
||||
MENUITEMINFO info;
|
||||
memset(&info, 0, sizeof info);
|
||||
info.cbSize = sizeof info;
|
||||
info.fMask = MIIM_STATE;
|
||||
GetMenuItemInfo(parent, instance, false, &info);
|
||||
return info.fState & MFS_ENABLED;
|
||||
}
|
||||
|
||||
pMenuControl::pMenuControl(MenuControl &self_) : pWidget(self_), self(self_) {
|
||||
parent = 0;
|
||||
text = 0;
|
||||
}
|
||||
|
||||
pMenuControl::~pMenuControl() {
|
||||
if(text) free(text);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
class pMenuControl : public pWidget {
|
||||
public:
|
||||
void enable(bool = true);
|
||||
void disable();
|
||||
bool enabled();
|
||||
|
||||
MenuControl &self;
|
||||
pMenuControl(MenuControl&);
|
||||
virtual ~pMenuControl();
|
||||
|
||||
/* internal */
|
||||
HMENU parent;
|
||||
char *text;
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
void pMenuGroup::create(const char *text_) {
|
||||
group = CreatePopupMenu();
|
||||
text = strdup(text_);
|
||||
}
|
||||
|
||||
void pMenuGroup::attach(MenuControl &menucontrol) {
|
||||
switch(menucontrol.type) {
|
||||
case Widget::MenuGroupType: {
|
||||
AppendMenu(group, MF_STRING | MF_POPUP, (uint)((MenuGroup&)menucontrol).p.group, menucontrol.p.text);
|
||||
} break;
|
||||
|
||||
case Widget::MenuItemType:
|
||||
case Widget::MenuCheckItemType:
|
||||
case Widget::MenuRadioItemType: {
|
||||
AppendMenu(group, MF_STRING, menucontrol.p.instance, menucontrol.p.text);
|
||||
if(menucontrol.type == Widget::MenuRadioItemType && ((MenuRadioItem&)menucontrol).p.create_checked) {
|
||||
CheckMenuItem(group, menucontrol.p.instance, MF_CHECKED);
|
||||
}
|
||||
} break;
|
||||
|
||||
case Widget::MenuSeparatorType: {
|
||||
AppendMenu(group, MF_SEPARATOR, menucontrol.p.instance, "");
|
||||
} break;
|
||||
}
|
||||
|
||||
menucontrol.p.parent = group;
|
||||
}
|
||||
|
||||
pMenuGroup::pMenuGroup(MenuGroup &self_) : pMenuControl(self_), self(self_) {
|
||||
group = 0;
|
||||
}
|
||||
Loaded 100 of 354 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user