Update to bsnes v019r09 release.

Alright, I'm in a semi-good mood.







    http://byuu.cinnamonpirate.com/files/bsnes_v019_wip9.zip




 This one uses the old win32 interface, and adds a new feature I'd
like people with sound troubles to try out. The config file now
contains "audio.latency". Don't mess with "audio.frequency", it won't
do you any good and gets overridden by the speed regulation settings
for now.

 The audio.latency is a precise measurement of the millisecond delay
between sound being output by a real SNES and hearing that same sound
in bsnes. It takes into account the current playback frequency, as
well as the three-ring buffering system used by bsnes' audio system.
 Formula: sample_latency = CURRENT_playback_frequency / 1000 *
config_file_latency * 3 (so 32khz + 75ms latency means each ring
buffer is 800 samples long). The new formula should make latency sound
better (it's consistent now) on fast / slow emulation speed throttling
settings as well.
 I also cut out the fourth ring, since it was redundant. This should
make bsnes appear ~25% more responsive to sound with the same buffer
latency. As a result, I increased the latency to 75ms (it was at ~45
before).
 I'd like to know what the lowest good value is that works on 95% of
sound cards, so I can use that. I'll let people with cheap sound cards
increase their latency setting manually (eventually it will be an
option in the GUI).

               **NOTE:** this version does nothing for triple
buffering/vsync/whatever. You must _disable_ triple buffering to try
out the latency settings. This version is strictly to test audio
playback support.

 I also added in my audio point resampler. Good god, it sounds
terrible. Regardless of the latency setting (either really high or
really low), the pitch difference between each audio ring is
_extremely_ noticeable. The code is there now in
src/ui/audio/dsound.cpp : AudioDS::run_videosync(), if anyone would
like to take a look. I'll hold my breath ;)

               -----

 Comparisons against ZSNES at this point are rather silly. Aside from
much more flexible timings, it probably has a nice audio resampler,
which I don't. If I faked CPU/SMP clock timings, I could get the SNES
spitting out 60 frames a second and 32khz audio a second. I'm not
going to do that, so I have to figure out how to resample the two. All
of my attempts at resampling video _and_ audio have both failed
miserably to date. I really only need one of those to work to get
smooth video+audio, but both would be nice so the user can decide
what's more important to them.

I don't care to add 2xSaI. I'm planning on redoing the filter stuff
soon to support 32-bit output for Xv, so if someone wants to add 2xSaI
support to bsnes after that, I'll add it in. Otherwise, HQ2x is
superior and Scale2x looks about the same, yet is way faster.

 Regarding the IPS thing, exactly. As I said, IPS is a bad format. You
can't tell if you need to patch against a headered or unheadered ROM
unless you read the documentation that fuckheads like Cowering remove
in their ROM sets ("at least it's already prepatched"), or try
patching twice to see which one works. UPS will eliminate both of
these problems. Readmes will be included inside the patches, and UPS
will work regardless if your ROM has a header or not. It will also be
reversible. It'll be better in every regard over IPS, so I have no
reason to support IPS.

 Lastly, I don't have any intention of working on fixing DeJap's
patch, regardless of where the problem is, as I have no way to run the
game on my copier. Maybe when and if the last two serious bugs
(Uniracers and Koushien 2) get fixed, I'll take a look at it then.
This commit is contained in:
byuu 2007-01-31 00:00:24 +00:00
parent b01f18c34c
commit 6d66b1136d
123 changed files with 4429 additions and 2200 deletions

BIN
bsnes.exe Normal file

Binary file not shown.

BIN
cart.db Normal file

Binary file not shown.

267
src/Makefile Normal file
View File

@ -0,0 +1,267 @@
######################
### bsnes makefile ###
######################
ifeq ($(PLATFORM),)
_null_: help
endif
##################################
### platform-specific settings ###
##################################
ifeq ($(PLATFORM),x-gcc-lui)
OS = unix
CC = gcc
CFLAGS = -O3 -fomit-frame-pointer -ffast-math -DPLATFORM_X -DCOMPILER_GCC -DPROCESSOR_X86 -DUI_LUI `pkg-config --cflags gtk+-2.0` `sdl-config --cflags`
AS = nasm
ASFLAGS = -f elf
LIBS = `pkg-config --libs gtk+-2.0` `sdl-config --libs` -lXv -lao
endif
ifeq ($(PLATFORM),x-gcc-sdl)
OS = unix
CC = gcc
CFLAGS = -O3 -fomit-frame-pointer -ffast-math -DPLATFORM_X -DCOMPILER_GCC -DPROCESSOR_X86 -DUI_SDL `sdl-config --cflags`
AS = nasm
ASFLAGS = -f elf
LIBS = `sdl-config --libs` -lao
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
endif
ifeq ($(PLATFORM),win-visualc)
OS = win
CC = cl
CFLAGS = /nologo /wd4996 /O2 /EHsc /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_WIN
AS = nasm
ASFLAGS = -f win32 -DWIN32
LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib
endif
ifeq ($(PLATFORM),win-visualc-pgi)
OS = win
CC = cl
CFLAGS = /nologo /wd4996 /O2 /GL /EHsc /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_WIN
AS = nasm
ASFLAGS = -f win32 -DWIN32
LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib
LINK = /link /PGD:bsnes.pgd /LTCG:PGINSTRUMENT
endif
ifeq ($(PLATFORM),win-visualc-pgo)
OS = win
CC = cl
CFLAGS = /nologo /wd4996 /O2 /GL /EHsc /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_WIN
AS = nasm
ASFLAGS = -f win32 -DWIN32
LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib
LINK = /link /PGD:bsnes.pgd /LTCG:PGOPTIMIZE
endif
ifeq ($(PLATFORM),win-visualc-sdl)
OS = win
CC = cl
CFLAGS = /nologo /wd4996 /O2 /EHsc /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_SDL
AS = nasm
ASFLAGS = -f win32 -DWIN32
LIBS = sdlmain.lib sdl.lib dsound.lib
endif
#####################################
### compiler / assembler switches ###
#####################################
ifeq ($(CC),gcc)
OUT = -obsnes
CPP = 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
###################
### OS switches ###
###################
ifeq ($(OS),unix)
RM = rm -f
endif
ifeq ($(OS),win)
OUT := $(OUT).exe
RM = del
LIBS += kernel32.lib user32.lib gdi32.lib winmm.lib comdlg32.lib comctl32.lib
endif
####################################
### main target and dependencies ###
####################################
OBJECTS = main.$(OBJ) libco_x86.$(OBJ) libstring.$(OBJ) libconfig.$(OBJ) \
reader.$(OBJ) cart.$(OBJ) cheat.$(OBJ) memory.$(OBJ) bmemory.$(OBJ) \
cpu.$(OBJ) scpu.$(OBJ) smp.$(OBJ) ssmp.$(OBJ) bdsp.$(OBJ) ppu.$(OBJ) \
bppu.$(OBJ) snes.$(OBJ) srtc.$(OBJ) sdd1.$(OBJ) c4.$(OBJ) dsp1.$(OBJ) \
dsp2.$(OBJ) obc1.$(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
endif
all: $(OBJECTS)
$(CPP) $(OUT) $(CFLAGS) $(OBJECTS) $(LIBS) $(LINK)
# mt -nologo -manifest bsnes.exe.manifest -outputresource:bsnes.exe;1
######################
### 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/settings/* \
ui/win/* ui/win/settings/* ui/win/debugger/* \
ui/sdl/*
bsnes.res : ui/bsnes.rc ; rc /r /fobsnes.res ui/bsnes.rc
#################
### libraries ###
#################
libco_x86.$(OBJ): lib/libco_x86.asm lib/*
libstring.$(OBJ): lib/libstring.cpp lib/*
libconfig.$(OBJ): lib/libconfig.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/*
###########
### 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 ###
###########
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/video/* snes/audio/* snes/input/*
#####################
### special chips ###
#####################
srtc.$(OBJ): chip/srtc/srtc.cpp chip/srtc/*
sdd1.$(OBJ): chip/sdd1/sdd1.cpp chip/sdd1/*
c4.$(OBJ) : chip/c4/c4.cpp chip/c4/*
dsp1.$(OBJ): chip/dsp1/dsp1.cpp chip/dsp1/*
dsp2.$(OBJ): chip/dsp2/dsp2.cpp chip/dsp2/*
obc1.$(OBJ): chip/obc1/obc1.cpp chip/obc1/*
############
### 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 Please specify which platform to compile for with PLATFORM=platform_name

View File

@ -1,4 +1,4 @@
#define BSNES_VERSION "0.019" #define BSNES_VERSION "0.019.09"
#define BSNES_TITLE "bsnes v" BSNES_VERSION #define BSNES_TITLE "bsnes v" BSNES_VERSION
#define MEMCORE bMemBus #define MEMCORE bMemBus
@ -13,12 +13,6 @@
//game genie + pro action replay code support (~1-3% speed hit) //game genie + pro action replay code support (~1-3% speed hit)
#define CHEAT_SYSTEM #define CHEAT_SYSTEM
//enable GZ, ZIP format support
//#define GZIP_SUPPORT
//enable JMA support
//#define JMA_SUPPORT
//snes core polymorphism //snes core polymorphism
//(allow runtime cpu/smp/dsp/ppu/bus selection, ~10% speed hit) //(allow runtime cpu/smp/dsp/ppu/bus selection, ~10% speed hit)
//#define POLYMORPHISM //#define POLYMORPHISM
@ -38,8 +32,6 @@
#include "lib/libco_x86.h" #include "lib/libco_x86.h"
#include "lib/libarray.h" #include "lib/libarray.h"
#include "lib/libvector.h" #include "lib/libvector.h"
#include "lib/libfile.h"
#include "lib/libups.h"
#include "lib/libstring.h" #include "lib/libstring.h"
#include "lib/libconfig.h" #include "lib/libconfig.h"

181
src/bsnes_lui.cfg Normal file
View File

@ -0,0 +1,181 @@
# Default path to look for ROM files in ("" = use default directory)
# (default = "")
path.rom = "/dos/Documents and Settings/byuu/Desktop/snes_testroms"
# Default path for all save RAM and cheat files ("" = use current directory)
# (default = "")
path.save = ""
# Path where BIOS file(s) are located
# Supported BIOS files:
# stbios.bin - Bandai Sufami Turbo
# (default = "./bios")
path.bios = "./bios"
# Extension to be used for all save RAM files
# (default = "srm")
path.save_ext = "srm"
# Use precalculated TV-style gamma ramp
# (default = true)
snes.colorfilter.gamma_ramp = true
# Convert color to sepia tone
# (default = false)
snes.colorfilter.sepia = false
# Convert color to grayscale tone
# (default = false)
snes.colorfilter.grayscale = false
# Invert output image colors
# (default = false)
snes.colorfilter.invert = false
# Contrast
# (default = 0)
snes.colorfilter.contrast = 0
# Brightness
# (default = 0)
snes.colorfilter.brightness = 0
# Gamma
# (default = 80)
snes.colorfilter.gamma = 80
# Merge fields in NTSC video filter
# Set to true if using filter at any refresh rate other than 60hz
#
# (default = true)
snes.ntsc_merge_fields = true
# Mutes SNES audio output when enabled
# (default = false)
snes.mute = false
# Controller attached to SNES port 1
# (default = 1)
snes.controller_port_1 = 1
# Controller attached to SNES port 2
# (default = 2)
snes.controller_port_2 = 2
# NTSC S-CPU clock rate (in hz)
# (default = 21477272)
cpu.ntsc_clock_rate = 21477272
# PAL S-CPU clock rate (in hz)
# (default = 21281370)
cpu.pal_clock_rate = 21281370
# NTSC S-SMP clock rate (in hz)
# (default = 24606720)
smp.ntsc_clock_rate = 24606720
# PAL S-SMP clock rate (in hz)
# (default = 24606720)
smp.pal_clock_rate = 24606720
# Approximate HCLOCK position to render at for scanline-based renderers
# (default = 512)
ppu.hack.render_scanline_position = 512
# Cache OAM OBJ attributes one scanline before rendering
# This is technically closer to the actual operation of the SNES,
# but can cause problems in many games if enabled
# (default = false)
ppu.hack.obj_cache = false
# Video hardware interface
# (default = "")
system.video = ""
# Audio hardware interface
# (default = "")
system.audio = ""
# Input hardware interface
# (default = "")
system.input = ""
# Regulate speed to 60hz (NTSC) / 50hz (PAL)
# (default = true)
system.regulate_speed = true
# Slowest speed setting (in hz)
# (default = 16000)
system.speed_slowest = 16000
# Slow speed setting
# (default = 24000)
system.speed_slow = 24000
# Normal speed setting
# (default = 32000)
system.speed_normal = 32000
# Fast speed setting
# (default = 48000)
system.speed_fast = 48000
# Fastest speed setting
# (default = 64000)
system.speed_fastest = 64000
# Windowed video profile configuration
# If available, please use bsnes GUI configuration editor to modify video profile settings
# Format: software_filter;hardware_filter;video_standard;multiplier;correct_aspect_ratio;
# enable_scanlines;manual_render_size;render_width;render_height;
# triple_buffering;resolution_width;resolution_height;refresh_rate
# (default = "0;1;0;2;true;false;false;595;448;false;0;0;0")
video.profile_win = "0;1;0;2;true;false;false;595;448;false;0;0;0"
# Fullscreen video profile configuration
# (default = "0;1;0;2;true;false;false;595;448;false;0;0;0")
video.profile_full = "0;1;0;2;true;false;false;595;448;false;0;0;0"
# Use Video RAM instead of System RAM
# (default = true)
video.use_vram = true
# Progressive scanline intensity
# Value is percentage of intensity from 0 to 100
# (default = 30)
video.pscanline_intensity = 30
# Interlace scanline intensity
# (default = 50)
video.iscanline_intensity = 50
# Axis resistance for all analog joypads
# Affects responsiveness of analog stick movement by specifying what percentage
# in any given direction the axis must be pressed to trigger a button press.
# In other words, this determines how hard you have to press the analog stick to
# simulate pressing e.g. left or right on a digital joypad.
# Value is a percentage, from 0 (axis will trigger with virtually any axis movement)
# up to 100 (axis must be pressed fully to given corner).
# Value affects all four directions of the axis equally.
# Note: Values below 10 or above 90 are not recommended and may not work at all.
# (default = 75)
input.axis_resistance = 75
# Allow up+down and left+right key combinations for joypad 1 (not recommended)
# (default = false)
input.joypad1.allow_invalid_input = false
# Joypad 1 button map
# Format: Up; Down; Left; Right; A; B; X; Y; L; R; Select; Start
# (default = "up | joypad0.up; down | joypad0.down; left | joypad0.left; right | joypad0.right; x | joypad0.button3; z | joypad0.button2; s | joypad0.button1; a | joypad0.button0; d | joypad0.button6; c | joypad0.button7; rshift | joypad0.button4; enter | joypad0.button5")
input.joypad1.map = "up | joypad0.up; down | joypad0.down; left | joypad0.left; right | joypad0.right; x | joypad0.button3; z | joypad0.button2; s | joypad0.button1; a | joypad0.button0; d | joypad0.button6; c | joypad0.button7; rshift | joypad0.button4; enter | joypad0.button5"
# Allow up+down and left+right key combinations for joypad 2 (not recommended)
# (default = false)
input.joypad2.allow_invalid_input = false
# Joypad 2 button map
# Format: Up; Down; Left; Right; A; B; X; Y; L; R; Select; Start
# (default = "t | joypad1.up; g | joypad1.down; f | joypad1.left; h | joypad1.right; k | joypad1.button3; j | joypad1.button2; i | joypad1.button1; u | joypad1.button0; o | joypad1.button6; l | joypad1.button7; lbracket | joypad1.button4; rbracket | joypad1.button5")
input.joypad2.map = "t | joypad1.up; g | joypad1.down; f | joypad1.left; h | joypad1.right; k | joypad1.button3; j | joypad1.button2; i | joypad1.button1; u | joypad1.button0; o | joypad1.button6; l | joypad1.button7; lbracket | joypad1.button4; rbracket | joypad1.button5"

View File

@ -1,15 +1,15 @@
#include "../base.h" #include "../base.h"
#include "database.cpp" #include "database.cpp"
#include "cart_normal.cpp"
#include "cart_st.cpp"
#include "cart_stdual.cpp"
#include "cart_file.cpp" #include "cart_file.cpp"
#include "cart_header.cpp" #include "cart_header.cpp"
Cartridge cartridge; Cartridge cartridge;
#include "cart_normal.cpp"
#include "cart_st.cpp"
#include "cart_stdual.cpp"
void Cartridge::load_begin(uint cart_type) { void Cartridge::load_begin(uint cart_type) {
if(loaded() == true)return; if(loaded() == true)return;

View File

@ -1,3 +1,14 @@
#include "../reader/filereader.h"
#if defined(GZIP_SUPPORT)
#include "../reader/gzreader.h"
#include "../reader/zipreader.h"
#endif
#if defined(JMA_SUPPORT)
#include "../reader/jmareader.h"
#endif
bool Cartridge::load_file(const char *fn, uint8 *&data, uint &size) { bool Cartridge::load_file(const char *fn, uint8 *&data, uint &size) {
dprintf("* Loading \"%s\"...", fn); dprintf("* Loading \"%s\"...", fn);

3
src/cc.bat Normal file
View File

@ -0,0 +1,3 @@
@make -r PLATFORM=win-visualc
@move bsnes.exe ../bsnes.exe>nul
@pause

2
src/cc.sh Normal file
View File

@ -0,0 +1,2 @@
#!/bin/sh
gmake PLATFORM=x-gcc-lui

View File

@ -1,4 +1,5 @@
#include "../base.h" #include "../base.h"
#include "../reader/filereader.h"
Cheat cheat; Cheat cheat;

2
src/clean.sh Normal file
View File

@ -0,0 +1,2 @@
#!/bin/sh
gmake PLATFORM=x-gcc-lui clean

View File

@ -172,7 +172,7 @@ void sCPU::cycle_edge() {
status.hdmainit_triggered = true; status.hdmainit_triggered = true;
hdma_init_reset(); hdma_init_reset();
if(hdma_enabled_channels()) { if(hdma_enabled_channels()) {
add_clocks(12); add_clocks(18);
hdma_init(); hdma_init();
//if(status.dma_state == DMASTATE_INACTIVE) { //if(status.dma_state == DMASTATE_INACTIVE) {
// status.dma_state = DMASTATE_DMASYNC; // status.dma_state = DMASTATE_DMASYNC;
@ -188,7 +188,7 @@ void sCPU::cycle_edge() {
if(status.hclock >= 1106) { if(status.hclock >= 1106) {
status.hdma_triggered = true; status.hdma_triggered = true;
if(hdma_active_channels()) { if(hdma_active_channels()) {
add_clocks(12); add_clocks(18);
hdma_run(); hdma_run();
//if(status.dma_state == DMASTATE_INACTIVE) { //if(status.dma_state == DMASTATE_INACTIVE) {
// status.dma_state = DMASTATE_DMASYNC; // status.dma_state = DMASTATE_DMASYNC;
@ -250,7 +250,7 @@ void sCPU::timing_reset() {
status.prev_line_clocks = 1364; status.prev_line_clocks = 1364;
status.line_rendered = false; status.line_rendered = false;
status.line_render_position = minmax<0, 1112>((uint16)config::ppu.hack.render_scanline_position); status.line_render_position = min(1112, (uint16)config::ppu.hack.render_scanline_position);
status.dram_refreshed = false; status.dram_refreshed = false;
status.dram_refresh_position = (cpu_version == 1) ? 530 : 538; status.dram_refresh_position = (cpu_version == 1) ? 530 : 538;

View File

@ -1,5 +1,5 @@
/* /*
libarray : version 0.07 ~byuu (10/14/06) libarray : version 0.08 ~byuu (2006-12-16)
*/ */
#ifndef __LIBARRAY #ifndef __LIBARRAY
@ -25,14 +25,10 @@ protected:
public: public:
uint size() { return buffersize; } uint size() { return buffersize; }
uint capacity() { return buffersize; } uint capacity() { return poolsize; }
void reset() { void reset() {
if(pool) { safe_free(pool);
free(pool);
pool = 0;
}
poolsize = 0; poolsize = 0;
buffersize = 0; buffersize = 0;
} }
@ -44,7 +40,7 @@ public:
buffersize = size; buffersize = size;
} }
pool = static_cast<T*>(realloc(pool, sizeof(T) * size)); pool = (T*)realloc(pool, sizeof(T) * size);
poolsize = size; poolsize = size;
} }
@ -69,6 +65,17 @@ public:
~array() { reset(); } ~array() { reset(); }
array &operator=(array &source) {
safe_free(pool);
buffersize = source.buffersize;
poolsize = source.poolsize;
//allocate entire pool size ...
pool = (T*)realloc(pool, sizeof(T) * poolsize);
//... but only copy used pool objects
memcpy(pool, source.pool, sizeof(T) * buffersize);
return *this;
}
inline T &operator[](int index) { inline T &operator[](int index) {
if(index >= buffersize)resize(index + 1); if(index >= buffersize)resize(index + 1);
if(index >= buffersize)throw "array[] out of bounds"; if(index >= buffersize)throw "array[] out of bounds";

View File

@ -1,5 +1,5 @@
/* /*
libbase : version 0.08f ~byuu (2006-11-07) libbase : version 0.09 ~byuu (2007-01-12)
*/ */
#ifndef __LIBBASE #ifndef __LIBBASE
@ -11,6 +11,7 @@
#define NOMINMAX #define NOMINMAX
#define ftruncate _chsize #define ftruncate _chsize
#define putenv _putenv
#define vsnprintf _vsnprintf #define vsnprintf _vsnprintf
#endif #endif
@ -41,14 +42,19 @@
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <math.h> #include <math.h>
#include <io.h>
#if defined(_MSC_VER)
#include <io.h>
#else
#include <unistd.h>
#endif
#ifndef FALSE #ifndef FALSE
#define FALSE 0 #define FALSE 0
#endif #endif
#ifndef TRUE #ifndef TRUE
#define TRUE !FALSE #define TRUE (!FALSE)
#endif #endif
//deprecated //deprecated
@ -56,12 +62,43 @@
#define SafeDelete(__n) if(__n) { delete(__n); __n = 0; } #define SafeDelete(__n) if(__n) { delete(__n); __n = 0; }
#define SafeRelease(__n) if(__n) { __n->Release(); __n = 0; } #define SafeRelease(__n) if(__n) { __n->Release(); __n = 0; }
/*****
* template traits
*****/
template<typename T> struct is_reference { enum { value = false }; };
template<typename T> struct is_reference<T&> { enum { value = true }; };
template<typename T> struct is_pointer { enum { value = false }; };
template<typename T> struct is_pointer<T*> { enum { value = true }; };
template<typename T> struct is_const { enum { value = false }; };
template<typename T> struct is_const<const T> { enum { value = true }; };
template<typename T> struct is_const<const T&> { enum { value = true }; };
/*****
* null_t
*****/
struct null_t {
alwaysinline bool operator==(const null_t&) { return true; }
alwaysinline bool operator>=(const null_t&) { return true; }
alwaysinline bool operator<=(const null_t&) { return true; }
alwaysinline bool operator!=(const null_t&) { return false; }
alwaysinline bool operator> (const null_t&) { return false; }
alwaysinline bool operator< (const null_t&) { return false; }
alwaysinline null_t &operator=(const null_t&) { return *this; }
};
template<typename T> struct is_null_t { enum { value = false }; };
template<> struct is_null_t<null_t> { enum { value = true }; };
/***** /*****
* typedefs * typedefs
*****/ *****/
typedef unsigned int uint; typedef unsigned int uint;
typedef signed int sint; typedef signed int sint;
typedef unsigned char byte; typedef unsigned char byte;
typedef unsigned short word; typedef unsigned short word;
@ -74,10 +111,10 @@ typedef unsigned short uint16;
typedef unsigned long uint32; typedef unsigned long uint32;
typedef unsigned long long uint64; typedef unsigned long long uint64;
typedef signed char int8; typedef signed char int8;
typedef signed short int16; typedef signed short int16;
typedef signed long int32; typedef signed long int32;
typedef signed long long int64; typedef signed long long int64;
/***** /*****
* templates * templates
@ -113,12 +150,12 @@ T z = x;
#ifdef min #ifdef min
#undef min #undef min
#endif #endif
#define min(x, y) ((x < y) ? x : y) #define min(x, y) (((x) < (y)) ? (x) : (y))
#ifdef max #ifdef max
#undef max #undef max
#endif #endif
#define max(x, y) ((x > y) ? x : y) #define max(x, y) (((x) > (y)) ? (x) : (y))
template<int min, int max, typename T> inline T minmax(const T x) { 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; return (x < (T)min) ? (T)min : (x > (T)max) ? (T)max : x;
@ -390,7 +427,7 @@ uint32 size = ftell(fp);
return size; return size;
} }
static int ftruncate(FILE *fp, long size) { return ftruncate(fileno(fp), size); } static int fresize(FILE *fp, long size) { return ftruncate(fileno(fp), size); }
/***** /*****
* crc32 calculation * crc32 calculation

View File

@ -1,5 +1,5 @@
/* /*
libco_win32 : version 0.08 ~byuu (10/21/06) libco_win32 : version 0.09 ~byuu (2007-01-19)
win32-x86 implementation of libco win32-x86 implementation of libco
*/ */
@ -17,54 +17,57 @@ struct cothread_struct {
cothread_t __co_active = 0, __co_primary = 0; cothread_t __co_active = 0, __co_primary = 0;
void __stdcall co_entryproc(void *coentry) { void __stdcall co_entryproc(void *coentry);
cothread_struct *s = static_cast<cothread_struct*>(coentry); cothread_t co_init();
s->coentry();
co_exit(0);
}
cothread_t co_init() {
ConvertThreadToFiber(0);
cothread_struct *s = static_cast<cothread_struct*>(malloc(sizeof(cothread_struct)));
s->colink = 0;
s->coentry = 0;
s->cohandle = GetCurrentFiber();
__co_active = __co_primary = static_cast<cothread_t>(s);
return __co_active;
}
void co_term() {
//primary fiber cannot be deleted; free memory used by handle to fiber only
free(__co_primary);
//ConvertFiberToThread(); //only exists on WinXP+
}
cothread_t co_active() { cothread_t co_active() {
if(__co_primary == 0)co_init();
return __co_active; return __co_active;
} }
cothread_t co_create(cothread_p coentry, unsigned int heapsize) { cothread_t co_create(cothread_p coentry, unsigned int heapsize) {
cothread_struct *s = static_cast<cothread_struct*>(malloc(sizeof(cothread_struct))); if(__co_primary == 0)co_init();
cothread_struct *s = (cothread_struct*)malloc(sizeof(cothread_struct));
s->colink = co_active(); s->colink = co_active();
s->coentry = coentry; s->coentry = coentry;
s->cohandle = CreateFiber(heapsize + 512, co_entryproc, static_cast<void*>(s)); s->cohandle = CreateFiber(heapsize + 512, co_entryproc, (void*)s);
return static_cast<cothread_t>(s); return (cothread_t)s;
} }
void co_delete(cothread_t cothread) { void co_delete(cothread_t cothread) {
cothread_struct *s = static_cast<cothread_struct*>(cothread); cothread_struct *s = (cothread_struct*)cothread;
DeleteFiber(s->cohandle); DeleteFiber(s->cohandle);
free(cothread); free(cothread);
} }
void co_switch(cothread_t cothread) { void co_switch(cothread_t cothread) {
__co_active = cothread; __co_active = cothread;
cothread_struct *s = static_cast<cothread_struct*>(cothread); cothread_struct *s = (cothread_struct*)cothread;
SwitchToFiber(s->cohandle); SwitchToFiber(s->cohandle);
} }
void co_exit(cothread_t cothread) { void co_exit(cothread_t cothread) {
if(cothread != 0) { co_switch(cothread); } if(cothread != 0) { co_switch(cothread); }
cothread_struct *s = static_cast<cothread_struct*>(__co_active); cothread_struct *s = (cothread_struct*)__co_active;
co_switch(s->colink); co_switch(s->colink);
} }
/*****
* internal functions
*****/
void __stdcall co_entryproc(void *coentry) {
cothread_struct *s = (cothread_struct*)coentry;
s->coentry();
co_exit(0);
}
cothread_t co_init() {
ConvertThreadToFiber(0);
cothread_struct *s = (cothread_struct*)malloc(sizeof(cothread_struct));
s->colink = 0;
s->coentry = 0;
s->cohandle = GetCurrentFiber();
__co_active = __co_primary = (cothread_t)s;
return __co_active;
}

View File

@ -1,5 +1,5 @@
/* /*
libco_win32 : version 0.08 ~byuu (10/21/2006) libco_win32 : version 0.09 ~byuu (2007-01-19)
*/ */
#define COTHREAD_STACKSIZE_TINY 0x1000 #define COTHREAD_STACKSIZE_TINY 0x1000
@ -11,8 +11,6 @@
typedef void (*cothread_t); typedef void (*cothread_t);
typedef void (*cothread_p)(void); typedef void (*cothread_p)(void);
cothread_t co_init();
void co_term();
cothread_t co_active(); cothread_t co_active();
cothread_t co_create(cothread_p coentry, unsigned int heapsize); cothread_t co_create(cothread_p coentry, unsigned int heapsize);
void co_delete(cothread_t cothread); void co_delete(cothread_t cothread);

View File

@ -1,23 +1,38 @@
;***** ;*****
;libco_x86 : version 0.08 ~byuu (10/21/06) ;libco_x86 : version 0.09 ~byuu (2007-01-19)
;cross-platform x86 implementation of libco ;cross-platform x86 implementation of libco
;special thanks to Aaron Giles and Joel Yliluoma for various optimizations
; ;
;context save/restore adheres to c/c++ ABI ;[ABI compatibility]
;for x86 windows, osx, linux and freebsd ;- visual c++; windows-x86
;- mingw; windows-x86
;- gcc; osx86
;- gcc; linux-x86
;- gcc; freebsd-x86
; ;
;context saves esp+ebp+esi+edi+ebx ;[nonvolatile registers]
;context ignores eax+ecx+edx ;- esp, ebp, edi, esi, ebx
;context ignores st([0-7])+xmm[0-15] ;
;context ignores all else ;[volatile registers]
;- eax, ecx, edx
;- st0 - st7
;- xmm0 - xmm15
;***** ;*****
bits 32
section .bss
align 4
co_primary_buffer resb 512
section .data section .data
align 4 align 4
co_active_context dd 0 co_active_context dd 0
co_primary_context dd 0 co_primary_context dd 0
section .code section .text
;***** ;*****
;linker-specific name decorations ;linker-specific name decorations
@ -26,64 +41,35 @@ section .code
%define malloc _malloc %define malloc _malloc
%define free _free %define free _free
%define co_init @co_init@0
%define co_term @co_term@0
%define co_active @co_active@0 %define co_active @co_active@0
%define co_create @co_create@8 %define co_create @co_create@8
%define co_delete @co_delete@4 %define co_delete @co_delete@4
%define co_switch @co_switch@4 %define co_switch @co_switch@4
%define co_exit @co_exit@4 %define co_exit @co_exit@4
%define co_init @co_init@0
%endif %endif
%ifdef OSX86 %ifdef OSX86
%define malloc _malloc %define malloc _malloc
%define free _free %define free _free
%define co_init _co_init
%define co_term _co_term
%define co_active _co_active %define co_active _co_active
%define co_create _co_create %define co_create _co_create
%define co_delete _co_delete %define co_delete _co_delete
%define co_switch _co_switch %define co_switch _co_switch
%define co_exit _co_exit %define co_exit _co_exit
%define co_init _co_init
%endif %endif
extern malloc extern malloc
extern free extern free
global co_init
global co_term
global co_active global co_active
global co_create global co_create
global co_delete global co_delete
global co_switch global co_switch
global co_exit global co_exit
;*****
;extern "C" cothread_t fastcall co_init();
;return = eax
;*****
align 16
co_init:
;create context for main cothread
mov ecx,0 ;entry point for main thread is not needed
mov edx,512 ;main cothread uses default program stack
call co_create
mov dword[co_active_context],eax
mov dword[co_primary_context],eax
ret
;*****
;extern "C" void fastcall co_term();
;*****
align 16
co_term:
mov ecx,dword[co_primary_context]
call co_delete
ret
;***** ;*****
;extern "C" cothread_t fastcall co_active(); ;extern "C" cothread_t fastcall co_active();
;return = eax ;return = eax
@ -91,7 +77,11 @@ co_term:
align 16 align 16
co_active: co_active:
mov eax,dword[co_active_context] cmp dword[co_active_context],0
jnz .initialized
jmp co_init
.initialized
mov eax,[co_active_context]
ret ret
;***** ;*****
@ -103,34 +93,38 @@ co_active:
align 16 align 16
co_create: co_create:
cmp dword[co_active_context],0
jnz .initialized
call co_init
.initialized
;create heap space (stack + register storage) ;create heap space (stack + register storage)
add edx,512 ;+4(esp)+4(coentry)+4(colink)+256(stack_align) add edx,512 ;allocate extra memory for contextual info
push ecx push ecx
push edx push edx
push edx push edx
call malloc call malloc ;eax = malloc(edx)
add esp,4 add esp,4
pop edx pop edx
pop ecx pop ecx
add edx,eax ;set edx to point to top of stack heap add edx,eax ;set edx to point to top of stack heap
and edx,0xffffff00 ;force 256-byte alignment of stack heap and edx,-16 ;force 16-byte alignment of stack heap
;store thread entry point + registers so that first call to co_switch will execute coentry ;store thread entry point + registers, so that first call to co_switch will execute coentry
mov dword[edx-4],co_entrypoint ;edx=*stack mov dword[edx-4],co_entrypoint
mov dword[edx-8],0 mov dword[edx-8],0 ;ebp
mov dword[edx-12],0 mov dword[edx-12],0 ;esi
mov dword[edx-16],0 mov dword[edx-16],0 ;edi
mov dword[edx-20],0 mov dword[edx-20],0 ;ebx
sub edx,20 sub edx,20
;initialize context memory heap ;initialize context memory heap
mov dword[eax],edx ;cothread_t[ 0- 3] = stack heap pointer (esp) mov [eax],edx ;cothread_t[ 0- 3] = stack heap pointer (esp)
mov dword[eax+4],ecx ;cothread_t[ 4- 7] = entry point mov [eax+4],ecx ;cothread_t[ 4- 7] = entry point (coentry)
mov ecx,dword[co_active_context] mov ecx,[co_active_context]
mov dword[eax+8],ecx ;cothread_t[ 8-11] = return context mov [eax+8],ecx ;cothread_t[ 8-11] = return context
ret ;return allocated memory block as thread handle ret ;return allocated memory block as thread handle
@ -142,7 +136,7 @@ co_create:
align 16 align 16
co_delete: co_delete:
push ecx push ecx
call free call free ;free(ecx)
add esp,4 add esp,4
ret ret
@ -153,16 +147,16 @@ co_delete:
align 16 align 16
co_switch: co_switch:
mov eax,dword[co_active_context] ;backup current context mov eax,[co_active_context] ;backup current context
mov dword[co_active_context],ecx ;set new active context mov [co_active_context],ecx ;set new active context
push ebp push ebp
push esi push esi
push edi push edi
push ebx push ebx
mov dword[eax],esp mov [eax],esp
mov esp,dword[ecx] mov esp,[ecx]
pop ebx pop ebx
pop edi pop edi
pop esi pop esi
@ -181,8 +175,8 @@ co_exit:
jne co_switch jne co_switch
;if cothread is null, switch to context that created current context ;if cothread is null, switch to context that created current context
mov eax,dword[co_active_context] mov eax,[co_active_context]
mov ecx,dword[eax+8] mov ecx,[eax+8]
jmp co_switch jmp co_switch
;***** ;*****
@ -191,7 +185,19 @@ co_exit:
align 16 align 16
co_entrypoint: co_entrypoint:
mov eax,dword[co_active_context] mov eax,[co_active_context]
call dword[eax+4] call [eax+4]
xor ecx,ecx xor ecx,ecx
jmp co_exit jmp co_exit
;*****
;cothread_t fastcall co_init();
;return = eax
;*****
align 16
co_init:
mov eax,co_primary_buffer ;use pre-allocated memory for primary context
mov [co_active_context],eax
mov [co_primary_context],eax
ret

View File

@ -1,5 +1,5 @@
/* /*
libco_x86 : version 0.08 ~byuu (10/21/2006) libco_x86 : version 0.09 ~byuu (2007-01-13)
*/ */
#define COTHREAD_STACKSIZE_TINY 0x1000 #define COTHREAD_STACKSIZE_TINY 0x1000
@ -11,8 +11,6 @@
typedef void (*cothread_t); typedef void (*cothread_t);
typedef void (*cothread_p)(void); typedef void (*cothread_p)(void);
extern "C" cothread_t fastcall co_init();
extern "C" void fastcall co_term();
extern "C" cothread_t fastcall co_active(); extern "C" cothread_t fastcall co_active();
extern "C" cothread_t fastcall co_create(cothread_p coentry, unsigned int heapsize); extern "C" cothread_t fastcall co_create(cothread_p coentry, unsigned int heapsize);
extern "C" void fastcall co_delete(cothread_t cothread); extern "C" void fastcall co_delete(cothread_t cothread);

177
src/lib/libco_x86_64.asm Normal file
View File

@ -0,0 +1,177 @@
;*****
;libco_x86_64 : version 0.09 ~byuu (2007-01-19)
;cross-platform x86-64 implementation of libco
;special thanks to Aaron Giles and Joel Yliluoma for various optimizations
;
;[ABI compatibility]
;- SystemV ( http://refspecs.freestandards.org/elf/x86_64-SysV-psABI.pdf )
;- gcc; linux-x86-64
;- gcc; freebsd-x86-64
;
;[nonvolatile registers]
;- rsp, rbp, rbx, r12, r13, r14, r15
;
;[volatile registers]
;- rax, rcx, rdx, r8, r9, r10, r11, rdi, rsi
;- st0 - st7
;- xmm0 - xmm15
;*****
bits 64
section .bss
align 8
co_primary_buffer resb 512
section .data
align 8
co_active_context dq 0
co_primary_context dq 0
section .text
extern malloc
extern free
global co_active
global co_create
global co_delete
global co_switch
global co_exit
;*****
;extern "C" cothread_t co_active();
;return = rax
;*****
align 16
co_active:
cmp qword[co_active_context wrt rip],0
jnz .initialized
jmp co_init
.initialized
mov rax,[co_active_context wrt rip]
ret
;*****
;extern "C" cothread_t co_create(cothread_p coentry, unsigned int heapsize);
;rdi = coentry
;rsi = heapsize
;return = rax
;*****
align 16
co_create:
cmp qword[co_active_context wrt rip],0
jnz .initialized
call co_init
.initialized
;create heap space (stack + register storage)
add rsi,512 ;allocate extra memory for contextual info
push rdi
push rsi
mov rdi,rsi
call malloc ;rax = malloc(rdi)
pop rsi
pop rdi
add rsi,rax ;set rsi to point to top of stack heap
and rsi,-16 ;force 16-byte alignment of stack heap
;store thread entry point + registers, so that first call to co_switch will execute coentry
mov qword[rsi-8],co_entrypoint
mov qword[rsi-16],0 ;r15
mov qword[rsi-24],0 ;r14
mov qword[rsi-32],0 ;r13
mov qword[rsi-40],0 ;r12
mov qword[rsi-48],0 ;rbx
mov qword[rsi-56],0 ;rbp
mov qword[rsi-64],0 ;rsp
sub rsi,64
;initialize context memory heap
mov [rax],rsi ;cothread_t[ 0- 7] = stack heap pointer (rsp)
mov [rax+8],rdi ;cothread_t[ 8-15] = entry point (coentry)
mov rdi,[co_active_context wrt rip]
mov [rax+16],rdi ;cothread_t[16-23] = return context
ret ;return allocated memory block as thread handle
;*****
;extern "C" void co_delete(cothread_t cothread);
;rdi = cothread
;*****
align 16
co_delete:
jmp free ;free(rdi)
;*****
;extern "C" void co_switch(cothread_t cothread);
;rdi = cothread
;*****
align 16
co_switch:
mov rax,[co_active_context wrt rip] ;backup current context
mov [co_active_context wrt rip],rdi ;set new active context
push rbp
push rbx
push r12
push r13
push r14
push r15
mov [rax],rsp
mov rsp,[rdi]
pop r15
pop r14
pop r13
pop r12
pop rbx
pop rbp
ret
;*****
;extern "C" void co_exit(cothread_t cothread);
;rdi = cothread
;*****
align 16
co_exit:
cmp rdi,0
jne co_switch
;if cothread is null, switch to context that created current context
mov rax,[co_active_context wrt rip]
mov rdi,[rax+16]
jmp co_switch
;*****
;void co_entrypoint();
;*****
align 16
co_entrypoint:
mov rax,[co_active_context wrt rip]
call [rax+8]
xor rdi,rdi
jmp co_exit
;*****
;cothread_t co_init();
;return = rax
;*****
align 16
co_init:
mov rax,co_primary_buffer ;use pre-allocated memory for primary context
mov [co_active_context wrt rip],rax
mov [co_primary_context wrt rip],rax
ret

18
src/lib/libco_x86_64.h Normal file
View File

@ -0,0 +1,18 @@
/*
libco_x86_64 : version 0.09 ~byuu (2007-01-19)
*/
#define COTHREAD_STACKSIZE_TINY 0x2000
#define COTHREAD_STACKSIZE_SMALL 0x8000
#define COTHREAD_STACKSIZE_NORMAL 0x20000
#define COTHREAD_STACKSIZE_LARGE 0x80000
#define COTHREAD_STACKSIZE_HUGE 0x200000
typedef void (*cothread_t);
typedef void (*cothread_p)(void);
extern "C" cothread_t co_active();
extern "C" cothread_t co_create(cothread_p coentry, unsigned int heapsize);
extern "C" void co_delete(cothread_t cothread);
extern "C" void co_switch(cothread_t cothread);
extern "C" void co_exit(cothread_t cothread);

View File

@ -108,11 +108,11 @@ uint Config::string_to_uint(uint type, char *input) {
return (uint)false; return (uint)false;
} }
if(strbegin(input, "0x") || strbegin(input, "-0x")) { if(stribegin(input, "0x")) {
return sstrhex(input + 2); return strhex(input + 2);
} }
return sstrdec(input); return strdec(input);
} }
char *Config::uint_to_string(uint type, uint input) { char *Config::uint_to_string(uint type, uint input) {

View File

@ -1,5 +1,5 @@
/* /*
libconfig : version 0.11 ~byuu (2006/11/12) libconfig : version 0.12 ~byuu (2007-01-13)
*/ */
#ifndef __LIBCONFIG #ifndef __LIBCONFIG
@ -46,20 +46,30 @@ string char_data, char_def;
Setting(Config *_parent, char *_name, char *_desc, uint _data, uint _type); Setting(Config *_parent, char *_name, char *_desc, uint _data, uint _type);
Setting(Config *_parent, char *_name, char *_desc, char *_data); Setting(Config *_parent, char *_name, char *_desc, char *_data);
template<typename T> inline operator T() { return (T)get(); } inline operator uint() { return get(); }
template<typename T> inline Setting &operator=(const T &x) { set(x); return *this; } inline operator char*() { return strget(); }
template<typename T> inline bool operator==(const T &x) { return (T)get() == x; }
template<typename T> inline bool operator!=(const T &x) { return (T)get() != x; } template<typename T>
inline Setting &operator=(T x) {
(type != STR) ? set((uint)x) : strset((const char*)x);
return *this;
}
template<typename T>
inline bool operator==(T x) {
return (type != STR) ? get() == (uint)x : !strcmp(strget(), (const char*)x);
}
template<typename T>
inline bool operator!=(T x) {
return (type != STR) ? get() != (uint)x : strcmp(strget(), (const char*)x);
}
//numerical operations only
template<typename T> inline bool operator>=(const T &x) { return (T)get() >= x; } template<typename T> inline bool operator>=(const T &x) { return (T)get() >= x; }
template<typename T> inline bool operator> (const T &x) { return (T)get() > x; } template<typename T> inline bool operator> (const T &x) { return (T)get() > x; }
template<typename T> inline bool operator<=(const T &x) { return (T)get() <= x; } template<typename T> inline bool operator<=(const T &x) { return (T)get() <= x; }
template<typename T> inline bool operator< (const T &x) { return (T)get() < x; } template<typename T> inline bool operator< (const T &x) { return (T)get() < x; }
inline operator char*() { return strget(); }
inline Setting &operator=(char *x) { strset(x); return *this; }
inline Setting &operator=(const char *x) { strset(x); return *this; }
inline bool operator==(const char *x) { return !strcmp(strget(), x); }
inline bool operator!=(const char *x) { return strcmp(strget(), x); }
}; };
class Config { class Config {

View File

@ -1,451 +0,0 @@
/*
libfile : version 0.05a ~byuu (10/26/06)
*/
#ifndef __LIBFILE
#define __LIBFILE
/*****
* file object
*****/
class file {
public:
enum { mode_read, mode_write, mode_readwrite, mode_writeread };
enum { seek_start, seek_end, seek_back, seek_forward };
virtual void read(uint8 *data, uint length) = 0;
virtual uint8 read() = 0;
virtual void write(uint8 *data, uint length) = 0;
virtual void write(uint8 data) = 0;
virtual uint32 crc32();
virtual void seek(uint offset, uint mode = seek_start) = 0;
virtual void truncate(uint size) = 0;
virtual uint offset() = 0;
virtual uint size() = 0;
virtual bool eof() = 0;
virtual bool open(const char *filename, uint mode) = 0;
virtual bool open() = 0;
virtual bool flush() = 0;
virtual bool close() = 0;
};
inline uint32 file::crc32() {
uint pos = offset(), i = size();
seek(0);
uint32 crc32 = 0xffffffff;
while(i--) {
crc32 = crc32_adjust(crc32, read());
}
seek(pos);
return ~crc32;
}
/*****
* c++ wrappers
*****/
inline void fread(file &s, uint8 *data, uint length) { s.read(data, length); }
inline uint8 fread(file &s) { return s.read(); }
inline uint8 fgetc(file &s) { return s.read(); }
inline uint fgetb(file &s) { return s.read(); }
inline void fwrite(file &s, uint8 *data, uint length) { s.write(data, length); }
inline void fwrite(file &s, uint8 data) { s.write(data); }
inline void fputc(uint8 data, file &s) { s.write(data); }
inline void fputb(file &s, uint8 data) { s.write(data); }
inline uint32 fcrc32(file &s) { return s.crc32(); }
inline void fseek(file &s, uint offset, uint mode = file::seek_start) { s.seek(offset, mode); }
inline void ftruncate(file &s, uint size) { s.truncate(size); }
inline uint ftell(file &s) { return s.offset(); }
inline uint fsize(file &s) { return s.size(); }
inline bool feof(file &s) { return s.eof(); }
inline bool fopen(file &s, const char *filename, uint mode) { return s.open(filename, mode); }
inline bool fopen(file &s) { return s.open(); }
inline bool fflush(file &s) { return s.flush(); }
inline bool fclose(file &s) { return s.close(); }
/*****
* endian wrappers
*****/
inline uint8 fgetlb(file &s) { return fgetc(s); }
inline uint8 fgetmb(file &s) { return fgetc(s); }
inline uint16 fgetlw(file &s) {
return (fgetc(s)) | (fgetc(s) << 8);
}
inline uint16 fgetmw(file &s) {
return (fgetc(s) << 8) | (fgetc(s) << 8);
}
inline uint32 fgetld(file &s) {
return (fgetc(s)) | (fgetc(s) << 8) | (fgetc(s) << 16) | (fgetc(s) << 24);
}
inline uint32 fgetmd(file &s) {
return (fgetc(s) << 24) | (fgetc(s) << 16) | (fgetc(s) << 8) | (fgetc(s));
}
inline uint64 fgetlq(file &s) {
return ((uint64)fgetc(s) << 0) | ((uint64)fgetc(s) << 8) |
((uint64)fgetc(s) << 16) | ((uint64)fgetc(s) << 24) |
((uint64)fgetc(s) << 32) | ((uint64)fgetc(s) << 40) |
((uint64)fgetc(s) << 48) | ((uint64)fgetc(s) << 56);
}
inline uint64 fgetmq(file &s) {
return ((uint64)fgetc(s) << 56) | ((uint64)fgetc(s) << 48) |
((uint64)fgetc(s) << 40) | ((uint64)fgetc(s) << 32) |
((uint64)fgetc(s) << 24) | ((uint64)fgetc(s) << 16) |
((uint64)fgetc(s) << 8) | ((uint64)fgetc(s) << 0);
}
inline void fputlb(file &s, uint8 data) { fputc(data, s); }
inline void fputmb(file &s, uint8 data) { fputc(data, s); }
inline void fputlw(file &s, uint16 data) {
fputc(data >> 0, s);
fputc(data >> 8, s);
}
inline void fputmw(file &s, uint16 data) {
fputc(data >> 8, s);
fputc(data >> 0, s);
}
inline void fputld(file &s, uint32 data) {
fputc(data >> 0, s);
fputc(data >> 8, s);
fputc(data >> 16, s);
fputc(data >> 24, s);
}
inline void fputmd(file &s, uint32 data) {
fputc(data >> 24, s);
fputc(data >> 16, s);
fputc(data >> 8, s);
fputc(data >> 0, s);
}
inline void fputlq(file &s, uint64 data) {
fputc(data >> 0, s);
fputc(data >> 8, s);
fputc(data >> 16, s);
fputc(data >> 24, s);
fputc(data >> 32, s);
fputc(data >> 40, s);
fputc(data >> 48, s);
fputc(data >> 56, s);
}
inline void fputmq(file &s, uint64 data) {
fputc(data >> 56, s);
fputc(data >> 48, s);
fputc(data >> 40, s);
fputc(data >> 32, s);
fputc(data >> 24, s);
fputc(data >> 16, s);
fputc(data >> 8, s);
fputc(data >> 0, s);
}
/*****
* ramfile
*****/
class ramfile : public file {
private:
FILE *fp;
array<uint8> filedata;
char filename[1024];
uint filepos;
uint filesize;
uint filemode;
bool fileopen;
bool filevirtual;
public:
void read(uint8 *data, uint length) {
if(!fileopen || filemode == mode_write) { return; }
memcpy(data, filedata.get(filepos + length) + filepos, length);
filepos += length;
if(filepos > filesize)filepos = filesize;
}
uint8 read() {
if(!fileopen || filemode == mode_write) { return 0; }
if(eof() == true) { return 0xff; }
return filedata[filepos++];
}
void write(uint8 *data, uint length) {
if(!fileopen || filemode == mode_read) { return; }
memcpy(filedata.get(filepos + length) + filepos, data, length);
filepos += length;
if(filepos > filesize)filesize = filepos;
}
void write(uint8 data) {
if(!fileopen || filemode == mode_read) { return; }
filedata[filepos++] = data;
if(filepos > filesize)filesize = filepos;
}
void seek(uint offset, uint mode = seek_start) {
if(!fileopen) { return; }
switch(mode) {
case seek_start: filepos = offset; break;
case seek_end: filepos = filesize + offset; break;
case seek_back: filepos -= offset; break;
case seek_forward: filepos += offset; break;
}
if(filemode == mode_read) {
if(filepos > filesize)filepos = filesize;
} else {
if(filepos > filesize)filesize = filepos;
}
}
void truncate(uint size) {
filesize = size;
if(filepos > filesize)filepos = filesize;
}
uint offset() {
if(!fileopen) { return 0; }
return filepos;
}
uint size() {
if(!fileopen) { return 0; }
return filesize;
}
bool eof() {
if(!fileopen) { return true; }
return (filepos >= filesize);
}
bool open(const char *fn, uint mode) {
if(fileopen) { return false; }
strcpy(filename, fn ? fn : "");
filevirtual = (*filename == 0);
filemode = mode;
switch(filemode) {
case mode_read:
case mode_readwrite:
if(filevirtual == true) {
filesize = 0;
} else {
fp = fopen(filename, "rb");
if(!fp) { return false; }
filesize = fsize(fp);
fread(filedata.get(filesize), 1, filesize, fp);
fclose(fp);
}
break;
default:
filesize = 0;
break;
}
filepos = 0;
fileopen = true;
return true;
}
bool open() {
return fileopen;
}
bool flush() {
if(!fileopen) { return false; }
switch(filemode) {
case mode_readwrite:
case mode_write:
case mode_writeread:
if(filevirtual == false) {
fp = fopen(filename, "wb");
if(!fp) { return false; }
fwrite(filedata.get(filesize), 1, filesize, fp);
fclose(fp);
}
break;
}
return true;
}
bool close() {
if(!fileopen) { return false; }
bool result = flush();
fileopen = false;
filedata.reset();
return result;
}
ramfile() {
fileopen = false;
}
~ramfile() {
if(fileopen) { close(); }
}
};
/*****
* diskfile
*****/
class diskfile : public file {
private:
FILE *fp;
uint filemode;
public:
void read(uint8 *data, uint length) {
if(!fp || filemode == mode_write) { return; }
fread(data, 1, length, fp);
}
uint8 read() {
if(!fp || filemode == mode_write) { return 0; }
if(eof() == true) { return 0xff; }
return fgetc(fp);
}
void write(uint8 *data, uint length) {
if(!fp || filemode == mode_read) { return; }
fwrite(data, 1, length, fp);
}
void write(uint8 data) {
if(!fp || filemode == mode_read) { return; }
fputc(data, fp);
}
void seek(uint offset, uint mode = seek_start) {
if(!fp) { return; }
switch(mode) {
default:
case seek_start: fseek(fp, offset, SEEK_SET); break;
case seek_end: fseek(fp, offset, SEEK_END); break;
case seek_back: fseek(fp, offset, SEEK_CUR); break;
case seek_forward: fseek(fp, offset, SEEK_CUR); break;
}
}
void truncate(uint size) {
if(!fp) { return; }
ftruncate(fp, size);
}
uint offset() {
if(!fp) { return 0; }
return ftell(fp);
}
uint size() {
if(!fp) { return 0; }
uint pos = ftell(fp);
fseek(fp, 0, SEEK_END);
uint filesize = ftell(fp);
fseek(fp, pos, SEEK_SET);
return filesize;
}
bool eof() {
if(!fp) { return true; }
if(feof(fp)) {
seek(size(), seek_start);
return true;
}
return false;
}
bool open(const char *filename, uint mode) {
if(fp) { return false; }
filemode = mode;
char m[8];
switch(filemode) {
default:
case mode_read: strcpy(m, "rb"); break;
case mode_write: strcpy(m, "wb"); break;
case mode_readwrite: strcpy(m, "rb+"); break;
case mode_writeread: strcpy(m, "wb+"); break;
}
fp = fopen(filename, m);
if(!fp) { return false; }
return true;
}
bool open() {
return (fp != 0);
}
bool flush() {
if(!fp) { return false; }
fflush(fp);
return true;
}
bool close() {
if(!fp) { return false; }
fclose(fp);
fp = 0;
return true;
}
diskfile() {
fp = 0;
}
~diskfile() {
if(fp) { fclose(fp); }
}
};
/*****
* directory object
*****/
class directory {
public:
void open(const char *path) {}
void close() {}
uint read(char *filename, uint maxlength) { return 0; }
};
#endif

341
src/lib/libfunctor.h Normal file
View File

@ -0,0 +1,341 @@
/*
libfunctor : version 0.01 ~byuu (2007-01-04)
*/
#ifndef __LIBFUNCTOR
#define __LIBFUNCTOR
template<typename T> struct functor;
template<typename T> struct functor_t;
/*****
* macros
*****/
#define base_functor \
functor *f; \
virtual operator bool() const { return f && (bool)(*f); } \
virtual functor *copy() const { return f->copy(); } \
functor &operator=(const functor *source) { if(f) { delete f; } f = (source->f) ? source->copy() : 0; return *this; } \
functor &operator=(const functor &source) { if(f) { delete f; } f = (source.f) ? source.copy() : 0; return *this; } \
functor(const functor &source) { /* ........................ */ f = (source.f) ? source.copy() : 0; } \
functor() : f(0) {} \
~functor() { if(f && f != this) { delete f; } }
#define base_global_functor \
operator bool() const { return proc; } \
functor_t *copy() const { return new functor_t(*this); } \
functor_t(const functor_t &source) { proc = source.proc; }
#define base_member_functor \
operator bool() const { return obj && proc; } \
functor_t *copy() const { return new functor_t(*this); } \
functor_t(const functor_t &source) { obj = source.obj; proc = source.proc; } \
C *obj;
/*****
* parameters = 0
*****/
template<typename R>
struct functor<R (*)()> { base_functor
virtual R operator()() const { return (*f)(); }
};
template<typename R>
struct functor_t<R (*)()> : public functor<R (*)()> { base_global_functor
R (*proc)();
R operator()() const { return (*proc)(); }
functor_t(R (*_proc)()) : proc(_proc) { this->f = this; }
};
template<typename C, typename R>
struct functor_t<R (C::*)()> : public functor<R (*)()> { base_member_functor
R (C::*proc)();
R operator()() const { return (obj->*proc)(); }
functor_t(C *_obj, R (C::*_proc)()) : obj(_obj), proc(_proc) { this->f = this; }
};
template<typename R>
functor_t<R (*)()> make_functor(R (*proc)()) {
return functor_t<R (*)()>(proc);
}
template<typename C, typename R>
functor_t<R (C::*)()> make_functor(C *obj, R (C::*proc)()) {
return functor_t<R (C::*)()>(obj, proc);
}
/*****
* parameters = 1
*****/
template<typename R, typename P1>
struct functor<R (*)(P1)> { base_functor
virtual R operator()(P1 p1) const { return (*f)(p1); }
};
template<typename R, typename P1>
struct functor_t<R (*)(P1)> : public functor<R (*)(P1)> { base_global_functor
R (*proc)(P1);
R operator()(P1 p1) const { return (*proc)(p1); }
functor_t(R (*_proc)(P1)) : proc(_proc) { this->f = this; }
};
template<typename C, typename R, typename P1>
struct functor_t<R (C::*)(P1)> : public functor<R (*)(P1)> { base_member_functor
R (C::*proc)(P1);
R operator()(P1 p1) const { return (obj->*proc)(p1); }
functor_t(C *_obj, R (C::*_proc)(P1)) : obj(_obj), proc(_proc) { this->f = this; }
};
template<typename R, typename P1>
functor_t<R (*)(P1)> make_functor(R (*proc)(P1)) {
return functor_t<R (*)(P1)>(proc);
}
template<typename C, typename R, typename P1>
functor_t<R (C::*)(P1)> make_functor(C *obj, R (C::*proc)(P1)) {
return functor_t<R (C::*)(P1)>(obj, proc);
}
/*****
* parameters = 2
*****/
template<typename R, typename P1, typename P2>
struct functor<R (*)(P1, P2)> { base_functor
virtual R operator()(P1 p1, P2 p2) const { return (*f)(p1, p2); }
};
template<typename R, typename P1, typename P2>
struct functor_t<R (*)(P1, P2)> : public functor<R (*)(P1, P2)> { base_global_functor
R (*proc)(P1, P2);
R operator()(P1 p1, P2 p2) const { return (*proc)(p1, p2); }
functor_t(R (*_proc)(P1, P2)) : proc(_proc) { this->f = this; }
};
template<typename C, typename R, typename P1, typename P2>
struct functor_t<R (C::*)(P1, P2)> : public functor<R (*)(P1, P2)> { base_member_functor
R (C::*proc)(P1, P2);
R operator()(P1 p1, P2 p2) const { return (obj->*proc)(p1, p2); }
functor_t(C *_obj, R (C::*_proc)(P1, P2)) : obj(_obj), proc(_proc) { this->f = this; }
};
template<typename R, typename P1, typename P2>
functor_t<R (*)(P1, P2)> make_functor(R (*proc)(P1, P2)) {
return functor_t<R (*)(P1, P2)>(proc);
}
template<typename C, typename R, typename P1, typename P2>
functor_t<R (C::*)(P1, P2)> make_functor(C *obj, R (C::*proc)(P1, P2)) {
return functor_t<R (C::*)(P1, P2)>(obj, proc);
}
/*****
* parameters = 3
*****/
template<typename R, typename P1, typename P2, typename P3>
struct functor<R (*)(P1, P2, P3)> { base_functor
virtual R operator()(P1 p1, P2 p2, P3 p3) const { return (*f)(p1, p2, p3); }
};
template<typename R, typename P1, typename P2, typename P3>
struct functor_t<R (*)(P1, P2, P3)> : public functor<R (*)(P1, P2, P3)> { base_global_functor
R (*proc)(P1, P2, P3);
R operator()(P1 p1, P2 p2, P3 p3) const { return (*proc)(p1, p2, p3); }
functor_t(R (*_proc)(P1, P2, P3)) : proc(_proc) { this->f = this; }
};
template<typename C, typename R, typename P1, typename P2, typename P3>
struct functor_t<R (C::*)(P1, P2, P3)> : public functor<R (*)(P1, P2, P3)> { base_member_functor
R (C::*proc)(P1, P2, P3);
R operator()(P1 p1, P2 p2, P3 p3) const { return (obj->*proc)(p1, p2, p3); }
functor_t(C *_obj, R (C::*_proc)(P1, P2, P3)) : obj(_obj), proc(_proc) { this->f = this; }
};
template<typename R, typename P1, typename P2, typename P3>
functor_t<R (*)(P1, P2, P3)> make_functor(R (*proc)(P1, P2, P3)) {
return functor_t<R (*)(P1, P2, P3)>(proc);
}
template<typename C, typename R, typename P1, typename P2, typename P3>
functor_t<R (C::*)(P1, P2, P3)> make_functor(C *obj, R (C::*proc)(P1, P2, P3)) {
return functor_t<R (C::*)(P1, P2, P3)>(obj, proc);
}
/*****
* parameters = 4
*****/
template<typename R, typename P1, typename P2, typename P3, typename P4>
struct functor<R (*)(P1, P2, P3, P4)> { base_functor
virtual R operator()(P1 p1, P2 p2, P3 p3, P4 p4) const { return (*f)(p1, p2, p3, p4); }
};
template<typename R, typename P1, typename P2, typename P3, typename P4>
struct functor_t<R (*)(P1, P2, P3, P4)> : public functor<R (*)(P1, P2, P3, P4)> { base_global_functor
R (*proc)(P1, P2, P3, P4);
R operator()(P1 p1, P2 p2, P3 p3, P4 p4) const { return (*proc)(p1, p2, p3, p4); }
functor_t(R (*_proc)(P1, P2, P3, P4)) : proc(_proc) { this->f = this; }
};
template<typename C, typename R, typename P1, typename P2, typename P3, typename P4>
struct functor_t<R (C::*)(P1, P2, P3, P4)> : public functor<R (*)(P1, P2, P3, P4)> { base_member_functor
R (C::*proc)(P1, P2, P3, P4);
R operator()(P1 p1, P2 p2, P3 p3, P4 p4) const { return (obj->*proc)(p1, p2, p3, p4); }
functor_t(C *_obj, R (C::*_proc)(P1, P2, P3, P4)) : obj(_obj), proc(_proc) { this->f = this; }
};
template<typename R, typename P1, typename P2, typename P3, typename P4>
functor_t<R (*)(P1, P2, P3, P4)> make_functor(R (*proc)(P1, P2, P3, P4)) {
return functor_t<R (*)(P1, P2, P3, P4)>(proc);
}
template<typename C, typename R, typename P1, typename P2, typename P3, typename P4>
functor_t<R (C::*)(P1, P2, P3, P4)> make_functor(C *obj, R (C::*proc)(P1, P2, P3, P4)) {
return functor_t<R (C::*)(P1, P2, P3, P4)>(obj, proc);
}
/*****
* parameters = 5
*****/
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5>
struct functor<R (*)(P1, P2, P3, P4, P5)> { base_functor
virtual R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const { return (*f)(p1, p2, p3, p4, p5); }
};
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5>
struct functor_t<R (*)(P1, P2, P3, P4, P5)> : public functor<R (*)(P1, P2, P3, P4, P5)> { base_global_functor
R (*proc)(P1, P2, P3, P4, P5);
R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const { return (*proc)(p1, p2, p3, p4, p5); }
functor_t(R (*_proc)(P1, P2, P3, P4, P5)) : proc(_proc) { this->f = this; }
};
template<typename C, typename R, typename P1, typename P2, typename P3, typename P4, typename P5>
struct functor_t<R (C::*)(P1, P2, P3, P4, P5)> : public functor<R (*)(P1, P2, P3, P4, P5)> { base_member_functor
R (C::*proc)(P1, P2, P3, P4, P5);
R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5) const { return (obj->*proc)(p1, p2, p3, p4, p5); }
functor_t(C *_obj, R (C::*_proc)(P1, P2, P3, P4, P5)) : obj(_obj), proc(_proc) { this->f = this; }
};
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5>
functor_t<R (*)(P1, P2, P3, P4, P5)> make_functor(R (*proc)(P1, P2, P3, P4, P5)) {
return functor_t<R (*)(P1, P2, P3, P4, P5)>(proc);
}
template<typename C, typename R, typename P1, typename P2, typename P3, typename P4, typename P5>
functor_t<R (C::*)(P1, P2, P3, P4, P5)> make_functor(C *obj, R (C::*proc)(P1, P2, P3, P4, P5)) {
return functor_t<R (C::*)(P1, P2, P3, P4, P5)>(obj, proc);
}
/*****
* parameters = 6
*****/
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
struct functor<R (*)(P1, P2, P3, P4, P5, P6)> { base_functor
virtual R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) const { return (*f)(p1, p2, p3, p4, p5, p6); }
};
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
struct functor_t<R (*)(P1, P2, P3, P4, P5, P6)> : public functor<R (*)(P1, P2, P3, P4, P5, P6)> { base_global_functor
R (*proc)(P1, P2, P3, P4, P5, P6);
R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) const { return (*proc)(p1, p2, p3, p4, p5, p6); }
functor_t(R (*_proc)(P1, P2, P3, P4, P5, P6)) : proc(_proc) { this->f = this; }
};
template<typename C, typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
struct functor_t<R (C::*)(P1, P2, P3, P4, P5, P6)> : public functor<R (*)(P1, P2, P3, P4, P5, P6)> { base_member_functor
R (C::*proc)(P1, P2, P3, P4, P5, P6);
R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6) const { return (obj->*proc)(p1, p2, p3, p4, p5, p6); }
functor_t(C *_obj, R (C::*_proc)(P1, P2, P3, P4, P5, P6)) : obj(_obj), proc(_proc) { this->f = this; }
};
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
functor_t<R (*)(P1, P2, P3, P4, P5, P6)> make_functor(R (*proc)(P1, P2, P3, P4, P5, P6)) {
return functor_t<R (*)(P1, P2, P3, P4, P5, P6)>(proc);
}
template<typename C, typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
functor_t<R (C::*)(P1, P2, P3, P4, P5, P6)> make_functor(C *obj, R (C::*proc)(P1, P2, P3, P4, P5, P6)) {
return functor_t<R (C::*)(P1, P2, P3, P4, P5, P6)>(obj, proc);
}
/*****
* parameters = 7
*****/
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
struct functor<R (*)(P1, P2, P3, P4, P5, P6, P7)> { base_functor
virtual R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) const { return (*f)(p1, p2, p3, p4, p5, p6, p7); }
};
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
struct functor_t<R (*)(P1, P2, P3, P4, P5, P6, P7)> : public functor<R (*)(P1, P2, P3, P4, P5, P6, P7)> { base_global_functor
R (*proc)(P1, P2, P3, P4, P5, P6, P7);
R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) const { return (*proc)(p1, p2, p3, p4, p5, p6, p7); }
functor_t(R (*_proc)(P1, P2, P3, P4, P5, P6, P7)) : proc(_proc) { this->f = this; }
};
template<typename C, typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
struct functor_t<R (C::*)(P1, P2, P3, P4, P5, P6, P7)> : public functor<R (*)(P1, P2, P3, P4, P5, P6, P7)> { base_member_functor
R (C::*proc)(P1, P2, P3, P4, P5, P6, P7);
R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7) const { return (obj->*proc)(p1, p2, p3, p4, p5, p6, p7); }
functor_t(C *_obj, R (C::*_proc)(P1, P2, P3, P4, P5, P6, P7)) : obj(_obj), proc(_proc) { this->f = this; }
};
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
functor_t<R (*)(P1, P2, P3, P4, P5, P6, P7)> make_functor(R (*proc)(P1, P2, P3, P4, P5, P6, P7)) {
return functor_t<R (*)(P1, P2, P3, P4, P5, P6, P7)>(proc);
}
template<typename C, typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
functor_t<R (C::*)(P1, P2, P3, P4, P5, P6, P7)> make_functor(C *obj, R (C::*proc)(P1, P2, P3, P4, P5, P6, P7)) {
return functor_t<R (C::*)(P1, P2, P3, P4, P5, P6, P7)>(obj, proc);
}
/*****
* parameters = 8
*****/
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
struct functor<R (*)(P1, P2, P3, P4, P5, P6, P7, P8)> { base_functor
virtual R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) const { return (*f)(p1, p2, p3, p4, p5, p6, p7, p8); }
};
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
struct functor_t<R (*)(P1, P2, P3, P4, P5, P6, P7, P8)> : public functor<R (*)(P1, P2, P3, P4, P5, P6, P7, P8)> { base_global_functor
R (*proc)(P1, P2, P3, P4, P5, P6, P7, P8);
R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) const { return (*proc)(p1, p2, p3, p4, p5, p6, p7, p8); }
functor_t(R (*_proc)(P1, P2, P3, P4, P5, P6, P7, P8)) : proc(_proc) { this->f = this; }
};
template<typename C, typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
struct functor_t<R (C::*)(P1, P2, P3, P4, P5, P6, P7, P8)> : public functor<R (*)(P1, P2, P3, P4, P5, P6, P7, P8)> { base_member_functor
R (C::*proc)(P1, P2, P3, P4, P5, P6, P7, P8);
R operator()(P1 p1, P2 p2, P3 p3, P4 p4, P5 p5, P6 p6, P7 p7, P8 p8) const { return (obj->*proc)(p1, p2, p3, p4, p5, p6, p7, p8); }
functor_t(C *_obj, R (C::*_proc)(P1, P2, P3, P4, P5, P6, P7, P8)) : obj(_obj), proc(_proc) { this->f = this; }
};
template<typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
functor_t<R (*)(P1, P2, P3, P4, P5, P6, P7, P8)> make_functor(R (*proc)(P1, P2, P3, P4, P5, P6, P7, P8)) {
return functor_t<R (*)(P1, P2, P3, P4, P5, P6, P7, P8)>(proc);
}
template<typename C, typename R, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
functor_t<R (C::*)(P1, P2, P3, P4, P5, P6, P7, P8)> make_functor(C *obj, R (C::*proc)(P1, P2, P3, P4, P5, P6, P7, P8)) {
return functor_t<R (C::*)(P1, P2, P3, P4, P5, P6, P7, P8)>(obj, proc);
}
/*****
* epilogue
*****/
#undef base_functor
#undef base_global_functor
#undef base_member_functor
#endif

View File

@ -1,5 +1,5 @@
/* /*
libkeymap : version 0.02 ~byuu (07/30/06) libkeymap : version 0.02 ~byuu (2006-07-30)
*/ */
#ifndef __LIBKEYMAP #ifndef __LIBKEYMAP

View File

@ -31,4 +31,4 @@ void sort(T list[], uint length, Tcmp comparator) {
} }
} }
#endif __LIBSORT #endif

View File

@ -14,13 +14,12 @@ char chrupper(char c) {
return c; return c;
} }
char *strptr(string &str) { return str.s; } char *strptr(const string &str) { return str.s; }
uint strlen(const string &str) { return strlen(strptr(str)); }
uint strlen(string &str) { return strlen(strptr(str)); } int strcmp(const string &dest, const char *src) { return strcmp(strptr(dest), src); }
int strcmp(const char *dest, const string &src) { return strcmp(dest, strptr(src)); }
int strcmp(string &dest, const char *src) { return strcmp(strptr(dest), src); } int strcmp(const string &dest, const string &src) { return strcmp(strptr(dest), strptr(src)); }
int strcmp(const char *dest, string &src) { return strcmp(dest, strptr(src)); }
int strcmp(string &dest, string &src) { return strcmp(strptr(dest), strptr(src)); }
int __stricmp(const char *dest, const char *src) { int __stricmp(const char *dest, const char *src) {
while(*dest) { while(*dest) {
@ -30,22 +29,16 @@ int __stricmp(const char *dest, const char *src) {
} }
return (int)chrlower(*dest) - (int)chrlower(*src); return (int)chrlower(*dest) - (int)chrlower(*src);
} }
int stricmp(string &dest, const char *src) { return __stricmp(strptr(dest), src); } int stricmp(const string &dest, const char *src) { return __stricmp(strptr(dest), src); }
int stricmp(const char *dest, string &src) { return __stricmp(dest, strptr(src)); } int stricmp(const char *dest, const string &src) { return __stricmp(dest, strptr(src)); }
int stricmp(string &dest, string &src) { return __stricmp(strptr(dest), strptr(src)); } int stricmp(const string &dest, const string &src) { return __stricmp(strptr(dest), strptr(src)); }
void strcpy(string &dest, const char src) {
dest.reserve(2);
dest.s[0] = src;
dest.s[1] = 0;
}
void strcpy(string &dest, const char *src) { void strcpy(string &dest, const char *src) {
int srclen = strlen(src); int srclen = strlen(src);
dest.reserve(srclen); dest.reserve(srclen);
strcpy(dest.s, src); strcpy(dest.s, src);
} }
void strcpy(string &dest, string &src) { strcpy(dest, strptr(src)); } void strcpy(string &dest, const string &src) { strcpy(dest, strptr(src)); }
uint strlcpy(char *dest, const char *src, uint length) { uint strlcpy(char *dest, const char *src, uint length) {
uint srclen = strlen(src); uint srclen = strlen(src);
@ -61,25 +54,18 @@ uint strlcpy(string &dest, const char *src, uint length) {
return strlcpy(strptr(dest), src, length); return strlcpy(strptr(dest), src, length);
} }
uint strlcpy(string &dest, string &src, uint length) { uint strlcpy(string &dest, const string &src, uint length) {
dest.reserve(length); dest.reserve(length);
return strlcpy(strptr(dest), strptr(src), length); return strlcpy(strptr(dest), strptr(src), length);
} }
void strcat(string &dest, const char src) {
int length = strlen(dest);
dest.reserve(length + 1);
dest.s[length] = src;
dest.s[length + 1] = 0;
}
void strcat(string &dest, const char *src) { void strcat(string &dest, const char *src) {
int srclen = strlen(src); int srclen = strlen(src);
int destlen = strlen(dest); int destlen = strlen(dest);
dest.reserve(srclen + destlen); dest.reserve(srclen + destlen);
strcat(dest.s, src); strcat(dest.s, src);
} }
void strcat(string &dest, string &src) { strcat(dest, strptr(src)); } void strcat(string &dest, const string &src) { strcat(dest, strptr(src)); }
uint strlcat(char *dest, const char *src, uint length) { uint strlcat(char *dest, const char *src, uint length) {
uint destlen = strlen(dest), srclen = strlen(src); uint destlen = strlen(dest), srclen = strlen(src);
@ -95,7 +81,7 @@ uint strlcat(string &dest, const char *src, uint length) {
return strlcat(strptr(dest), src, length); return strlcat(strptr(dest), src, length);
} }
uint strlcat(string &dest, string &src, uint length) { uint strlcat(string &dest, const string &src, uint length) {
dest.reserve(length); dest.reserve(length);
return strlcat(strptr(dest), strptr(src), length); return strlcat(strptr(dest), strptr(src), length);
} }
@ -111,8 +97,7 @@ string temp;
} }
return temp; return temp;
} }
string substr(string &dest, const string &src, uint start, uint length) { return substr(dest, strptr(src), start, length); }
string substr(string &dest, string &src, uint start, uint length) { return substr(dest, strptr(src), start, length); }
void strinsert(string &dest, const char *src, uint pos) { void strinsert(string &dest, const char *src, uint pos) {
string temp; string temp;
@ -121,7 +106,7 @@ string temp;
strcat(dest, src); strcat(dest, src);
strcat(dest, temp); strcat(dest, temp);
} }
void strinsert(string &dest, string &src, uint pos) { strinsert(dest, strptr(src), pos); } void strinsert(string &dest, const string &src, uint pos) { strinsert(dest, strptr(src), pos); }
void strremove(string &dest, uint start, uint length) { void strremove(string &dest, uint start, uint length) {
int i, destlen = strlen(dest); int i, destlen = strlen(dest);
@ -154,24 +139,23 @@ uint i = 0;
} }
string &strupper(string &str) { strupper(strptr(str)); return str; } string &strupper(string &str) { strupper(strptr(str)); return str; }
bool strpos(const char *str, const char *key, uint &pos) { index_t strpos(const char *str, const char *key) {
int ssl = strlen(str), ksl = strlen(key); int ssl = strlen(str), ksl = strlen(key);
if(ksl > ssl)return false; if(ksl > ssl)return index_t(false);
for(int i = 0; i <= ssl - ksl; i++) { for(int i = 0; i <= ssl - ksl; i++) {
if(!memcmp(str + i, key, ksl)) { if(!memcmp(str + i, key, ksl)) {
pos = i; return index_t(true, i);
return true;
} }
} }
return false; return index_t(false);
} }
bool strpos(string &str, const char *key, uint &pos) { return strpos(strptr(str), key, pos); } index_t strpos(const string &str, const char *key) { return strpos(strptr(str), key); }
bool strpos(const char *str, string &key, uint &pos) { return strpos(str, strptr(key), pos); } index_t strpos(const char *str, const string &key) { return strpos(str, strptr(key)); }
bool strpos(string &str, string &key, uint &pos) { return strpos(strptr(str), strptr(key), pos); } index_t strpos(const string &str, const string &key) { return strpos(strptr(str), strptr(key)); }
bool qstrpos(const char *str, const char *key, uint &pos) { index_t qstrpos(const char *str, const char *key) {
int ssl = strlen(str), ksl = strlen(key); int ssl = strlen(str), ksl = strlen(key);
if(ksl > ssl)return false; if(ksl > ssl)return index_t(false);
for(int i = 0; i <= ssl - ksl;) { for(int i = 0; i <= ssl - ksl;) {
uint8 x = str[i]; uint8 x = str[i];
if(x == '\"' || x == '\'') { if(x == '\"' || x == '\'') {
@ -180,17 +164,16 @@ int ssl = strlen(str), ksl = strlen(key);
if(i >= ssl)i = z; if(i >= ssl)i = z;
} }
if(!memcmp(str + i, key, ksl)) { if(!memcmp(str + i, key, ksl)) {
pos = i; return index_t(true, i);
return true;
} else { } else {
i++; i++;
} }
} }
return false; return index_t(false);
} }
bool qstrpos(string &str, const char *key, uint &pos) { return qstrpos(strptr(str), key, pos); } index_t qstrpos(const string &str, const char *key) { return qstrpos(strptr(str), key); }
bool qstrpos(const char *str, string &key, uint &pos) { return qstrpos(str, strptr(key), pos); } index_t qstrpos(const char *str, const string &key) { return qstrpos(str, strptr(key)); }
bool qstrpos(string &str, string &key, uint &pos) { return qstrpos(strptr(str), strptr(key), pos); } index_t qstrpos(const string &str, const string &key) { return qstrpos(strptr(str), strptr(key)); }
void strtr(char *dest, const char *before, const char *after) { void strtr(char *dest, const char *before, const char *after) {
int sl = strlen(dest), bsl = strlen(before), asl = strlen(after); int sl = strlen(dest), bsl = strlen(before), asl = strlen(after);
@ -211,7 +194,7 @@ int i, ssl = strlen(str), ksl = strlen(key);
if(ksl > ssl)return false; if(ksl > ssl)return false;
return (!memcmp(str, key, ksl)); return (!memcmp(str, key, ksl));
} }
bool strbegin(string &str, const char *key) { return strbegin(strptr(str), key); } bool strbegin(const string &str, const char *key) { return strbegin(strptr(str), key); }
bool stribegin(const char *str, const char *key) { bool stribegin(const char *str, const char *key) {
int ssl = strlen(str), ksl = strlen(key); int ssl = strlen(str), ksl = strlen(key);
@ -227,14 +210,14 @@ int ssl = strlen(str), ksl = strlen(key);
} }
return true; return true;
} }
bool stribegin(string &str, const char *key) { return stribegin(strptr(str), key); } bool stribegin(const string &str, const char *key) { return stribegin(strptr(str), key); }
bool strend(const char *str, const char *key) { bool strend(const char *str, const char *key) {
int ssl = strlen(str), ksl = strlen(key); int ssl = strlen(str), ksl = strlen(key);
if(ksl > ssl)return false; if(ksl > ssl)return false;
return (!memcmp(str + ssl - ksl, key, ksl)); return (!memcmp(str + ssl - ksl, key, ksl));
} }
bool strend(string &str, const char *key) { return strend(strptr(str), key); } bool strend(const string &str, const char *key) { return strend(strptr(str), key); }
bool striend(const char *str, const char *key) { bool striend(const char *str, const char *key) {
int ssl = strlen(str), ksl = strlen(key); int ssl = strlen(str), ksl = strlen(key);
@ -250,7 +233,7 @@ int ssl = strlen(str), ksl = strlen(key);
} }
return true; return true;
} }
bool striend(string &str, const char *key) { return striend(strptr(str), key); } bool striend(const string &str, const char *key) { return striend(strptr(str), key); }
void strltrim(char *str, const char *key) { void strltrim(char *str, const char *key) {
int i, ssl = strlen(str), ksl = strlen(key); int i, ssl = strlen(str), ksl = strlen(key);
@ -290,9 +273,21 @@ int ssl = strlen(str), ksl = strlen(key);
} }
void strirtrim(string &str, const char *key) { strirtrim(strptr(str), key); } void strirtrim(string &str, const char *key) { strirtrim(strptr(str), key); }
//does not work on type char* because function increases string length void strtrim(char *str, const char *key) {
strltrim(str, key);
strrtrim(str, key);
}
void strtrim(string &str, const char *key) { strtrim(strptr(str), key); }
void stritrim(char *str, const char *key) {
striltrim(str, key);
strirtrim(str, key);
}
void stritrim(string &str, const char *key) { stritrim(strptr(str), key); }
//does not support char* type because function increases string length
void strquote(string &str) { void strquote(string &str) {
static string t; string t;
strcpy(t, "\""); strcpy(t, "\"");
strcat(t, str); strcat(t, str);
strcat(t, "\""); strcat(t, "\"");
@ -321,9 +316,11 @@ bool strunquote(string &str) { return strunquote(strptr(str)); }
uint strhex(const char *str) { uint strhex(const char *str) {
uint r = 0, m = 0; uint r = 0, m = 0;
int i, ssl = strlen(str); int i = 0, ssl = strlen(str);
uint8 x; uint8 x;
for(i = 0; i < ssl; i++) { bool negate = (str[0] == '-');
if(negate)i++;
for(; i < ssl; i++) {
if(str[i] >= '0' && str[i] <= '9'); if(str[i] >= '0' && str[i] <= '9');
else if(str[i] >= 'A' && str[i] <= 'F'); else if(str[i] >= 'A' && str[i] <= 'F');
else if(str[i] >= 'a' && str[i] <= 'f'); else if(str[i] >= 'a' && str[i] <= 'f');
@ -334,87 +331,56 @@ uint8 x;
if(x >= '0' && x <= '9')x -= '0'; if(x >= '0' && x <= '9')x -= '0';
else if(x >= 'A' && x <= 'F')x -= 'A' - 0x0a; else if(x >= 'A' && x <= 'F')x -= 'A' - 0x0a;
else if(x >= 'a' && x <= 'f')x -= 'a' - 0x0a; else if(x >= 'a' && x <= 'f')x -= 'a' - 0x0a;
else return r; else break;
r |= x << m; r |= x << m;
} }
return r; return !negate ? r : (uint)-r;
} }
uint strhex(string &str) { return strhex(strptr(str)); } uint strhex(const string &str) { return strhex(strptr(str)); }
int sstrhex(const char *str) {
if(str[0] == '-') {
return -strhex(str + 1);
}
return strhex(str);
}
int sstrhex(string &str) { return sstrhex(strptr(str)); }
uint strdec(const char *str) { uint strdec(const char *str) {
uint m = 1; uint m = 1;
int i, r = 0, ssl = strlen(str); int i = 0, r = 0, ssl = strlen(str);
uint8 x; uint8 x;
for(i = 0; i < ssl; i++) { bool negate = (str[0] == '-');
if(negate)i++;
for(; i < ssl; i++) {
if(str[i] >= '0' && str[i] <= '9'); if(str[i] >= '0' && str[i] <= '9');
else break; else break;
} }
for(--i; i >= 0; i--, m *= 10) { for(--i; i >= 0; i--, m *= 10) {
x = str[i]; x = str[i];
if(x >= '0' && x <= '9')x -= '0'; if(x >= '0' && x <= '9')x -= '0';
else return r; else break;
r += x * m; r += x * m;
} }
return r; return !negate ? r : (uint)-r;
} }
uint strdec(string &str) { return strdec(strptr(str)); } uint strdec(const string &str) { return strdec(strptr(str)); }
int sstrdec(const char *str) {
if(str[0] == '-') {
return -strdec(str + 1);
}
return strdec(str);
}
int sstrdec(string &str) { return sstrdec(strptr(str)); }
uint strbin(const char *str) { uint strbin(const char *str) {
uint r = 0, m = 0; uint r = 0, m = 0;
int i, ssl = strlen(str); int i = 0, ssl = strlen(str);
uint8 x; uint8 x;
for(i = 0; i < ssl; i++) { bool negate = (str[0] == '-');
if(negate)i++;
for(; i < ssl; i++) {
if(str[i] == '0' || str[i] == '1'); if(str[i] == '0' || str[i] == '1');
else break; else break;
} }
for(--i; i >= 0; i--, m++) { for(--i; i >= 0; i--, m++) {
x = str[i]; x = str[i];
if(str[i] == '0' || str[i] == '1')x -= '0'; if(str[i] == '0' || str[i] == '1')x -= '0';
else return r; else break;
r |= x << m; r |= x << m;
} }
return r; return !negate ? r : (uint)-r;
} }
uint strbin(string &str) { return strbin(strptr(str)); } uint strbin(const string &str) { return strbin(strptr(str)); }
int sstrbin(const char *str) {
if(str[0] == '-') {
return -strbin(str + 1);
}
return strbin(str);
}
int sstrbin(string &str) { return sstrbin(strptr(str)); }
char *utoa(char *str, uint num) { char *utoa(char *str, uint num) {
char *pstr = str; sprintf(str, "%u", num);
uint mask = 1000000000; return str;
while(mask > num)mask /= 10;
while(mask > 1) {
str[0] = '0';
while(num >= mask) { str[0]++; num -= mask; }
str++;
mask /= 10;
}
str[0] = '0' + num;
str++;
str[0] = 0;
return pstr;
} }
string &utoa(string &str, uint num) { string &utoa(string &str, uint num) {
@ -424,14 +390,8 @@ string &utoa(string &str, uint num) {
} }
char *itoa(char *str, uint num) { char *itoa(char *str, uint num) {
char *pstr = str; sprintf(str, "%d", num);
if(num < 0) { return str;
str[0] = '-';
str++;
num = abs(int(num));
}
utoa(str, num);
return pstr;
} }
string &itoa(string &str, uint num) { string &itoa(string &str, uint num) {
@ -441,20 +401,8 @@ string &itoa(string &str, uint num) {
} }
char *htoa(char *str, uint num) { char *htoa(char *str, uint num) {
char *pstr = str; sprintf(str, "%x", num);
uint mask = 28, r; return str;
while(mask && ((num >> mask) & 15) == 0)mask -= 4;
while(mask) {
r = (num >> mask) & 15;
str[0] = (r < 10) ? ('0' + r) : ('a' + r - 10);
str++;
mask -= 4;
}
r = num & 15;
str[0] = (r < 10) ? ('0' + r) : ('a' + r - 10);
str++;
str[0] = 0;
return pstr;
} }
string &htoa(string &str, uint num) { string &htoa(string &str, uint num) {
@ -463,29 +411,6 @@ string &htoa(string &str, uint num) {
return str; return str;
} }
char *uhtoa(char *str, uint num) {
char *pstr = str;
uint mask = 28, r;
while(mask && ((num >> mask) & 15) == 0)mask -= 4;
while(mask) {
r = (num >> mask) & 15;
str[0] = (r < 10) ? ('0' + r) : ('A' + r - 10);
str++;
mask -= 4;
}
r = num & 15;
str[0] = (r < 10) ? ('0' + r) : ('A' + r - 10);
str++;
str[0] = 0;
return pstr;
}
string &uhtoa(string &str, uint num) {
str.reserve(16);
uhtoa(strptr(str), num);
return str;
}
char *btoa(char *str, uint num) { char *btoa(char *str, uint num) {
char *pstr = str; char *pstr = str;
uint mask = 0x80000000; uint mask = 0x80000000;
@ -502,7 +427,7 @@ uint mask = 0x80000000;
} }
string &btoa(string &str, uint num) { string &btoa(string &str, uint num) {
str.reserve(48); str.reserve(64);
btoa(strptr(str), num); btoa(strptr(str), num);
return str; return str;
} }

View File

@ -1,159 +1,155 @@
/* /*
libstring : version 0.14b ~byuu (2006/11/17) libstring : version 0.15 ~byuu (2007-01-13)
*/ */
#ifndef __LIBSTRING #ifndef __LIBSTRING
#define __LIBSTRING #define __LIBSTRING
#include "libbase.h"
#include "libvector.h" #include "libvector.h"
#include "libtuple.h"
class string; class string;
typedef linear_vector<string> stringarray; typedef linear_vector<string> stringarray;
char chrlower(char c); char chrlower(char c);
char chrupper(char c); char chrupper(char c);
uint count(stringarray &str); uint count(stringarray &str);
char *strptr(string &str); char *strptr(const string &str);
uint strlen(string &str); uint strlen(const string &str);
int strcmp(string &dest, const char *src); int strcmp(const string &dest, const char *src);
int strcmp(const char *dest, string &src); int strcmp(const char *dest, const string &src);
int strcmp(string &dest, string &src); int strcmp(const string &dest, const string &src);
//vc6/win32 and gcc/dos only support stricmp, whereas //vc6/win32 and gcc/dos only support stricmp, whereas
//gcc/unix only supports strcasecmp. this is an attempt //gcc/unix only supports strcasecmp. this is an attempt
//to avoid platform-specific defines... //to avoid platform-specific defines...
#define stricmp __stricmp #define stricmp __stricmp
int __stricmp(const char *dest, const char *src); int __stricmp(const char *dest, const char *src);
int stricmp(string &dest, const char *src); int stricmp(const string &dest, const char *src);
int stricmp(const char *dest, string &src); int stricmp(const char *dest, const string &src);
int stricmp(string &dest, string &src); int stricmp(const string &dest, const string &src);
void strcpy(string &dest, const char *src); void strcpy(string &dest, const char *src);
void strcpy(string &dest, string &src); void strcpy(string &dest, const string &src);
uint strlcpy(char *dest, const char *src, uint length); uint strlcpy(char *dest, const char *src, uint length);
uint strlcpy(string &dest, const char *src, uint length); uint strlcpy(string &dest, const char *src, uint length);
uint strlcpy(string &dest, string &src, uint length); uint strlcpy(string &dest, const string &src, uint length);
void strcat(string &dest, const char src); void strcat(string &dest, const char *src);
void strcat(string &dest, const char *src); void strcat(string &dest, const string &src);
void strcat(string &dest, string &src); uint strlcat(char *dest, const char *src, uint length);
uint strlcat(char *dest, const char *src, uint length); uint strlcat(string &dest, const char *src, uint length);
uint strlcat(string &dest, const char *src, uint length); uint strlcat(string &dest, const string &src, uint length);
uint strlcat(string &dest, string &src, uint length);
string substr(string &dest, const char *src, uint start = 0, uint length = 0); string substr(string &dest, const char *src, uint start = 0, uint length = 0);
string substr(string &dest, string &src, uint start = 0, uint length = 0); string substr(string &dest, const string &src, uint start = 0, uint length = 0);
void strinsert(string &dest, const char *src, uint pos); void strinsert(string &dest, const char *src, uint pos);
void strinsert(string &dest, string &src, uint pos); void strinsert(string &dest, const string &src, uint pos);
void strremove(string &dest, uint start, uint length = 0); void strremove(string &dest, uint start, uint length = 0);
char *strlower(char *str); char *strlower(char *str);
string &strlower(string &str); string &strlower(string &str);
char *strupper(char *str); char *strupper(char *str);
string &strupper(string &str); string &strupper(string &str);
bool strpos(const char *str, const char *key, uint &pos); typedef tuple<bool, uint> index_t;
bool strpos(string &str, const char *key, uint &pos); index_t strpos(const char *str, const char *key);
bool strpos(const char *str, string &key, uint &pos); index_t strpos(const string &str, const char *key);
bool strpos(string &str, string &key, uint &pos); index_t strpos(const char *str, const string &key);
index_t strpos(const string &str, const string &key);
bool qstrpos(const char *str, const char *key, uint &pos); index_t qstrpos(const char *str, const char *key);
bool qstrpos(string &str, const char *key, uint &pos); index_t qstrpos(const string &str, const char *key);
bool qstrpos(const char *str, string &key, uint &pos); index_t qstrpos(const char *str, const string &key);
bool qstrpos(string &str, string &key, uint &pos); index_t qstrpos(const string &str, const string &key);
void strtr(char *dest, const char *before, const char *after); void strtr(char *dest, const char *before, const char *after);
void strtr(string &dest, const char *before, const char *after); void strtr(string &dest, const char *before, const char *after);
bool strbegin(const char *str, const char *key); bool strbegin(const char *str, const char *key);
bool strbegin(string &str, const char *key); bool strbegin(const string &str, const char *key);
bool stribegin(const char *str, const char *key); bool stribegin(const char *str, const char *key);
bool stribegin(string &str, const char *key); bool stribegin(const string &str, const char *key);
bool strend(const char *str, const char *key); bool strend(const char *str, const char *key);
bool strend(string &str, const char *key); bool strend(const string &str, const char *key);
bool striend(const char *str, const char *key); bool striend(const char *str, const char *key);
bool striend(string &str, const char *key); bool striend(const string &str, const char *key);
void strltrim(char *str, const char *key); void strltrim(char *str, const char *key);
void strltrim(string &str, const char *key); void strltrim(string &str, const char *key);
void striltrim(char *str, const char *key); void striltrim(char *str, const char *key);
void striltrim(string &str, const char *key); void striltrim(string &str, const char *key);
void strrtrim(char *str, const char *key); void strrtrim(char *str, const char *key);
void strrtrim(string &str, const char *key); void strrtrim(string &str, const char *key);
void strirtrim(char *str, const char *key); void strirtrim(char *str, const char *key);
void strirtrim(string &str, const char *key); void strirtrim(string &str, const char *key);
void strquote(string &str); void strtrim(char *str, const char *key);
void strtrim(string &str, const char *key);
bool strunquote(char *str); void stritrim(char *str, const char *key);
bool strunquote(string &str); void stritrim(string &str, const char *key);
uint strhex(const char *str); void strquote(string &str);
uint strhex(string &str);
int sstrhex(const char *str); bool strunquote(char *str);
int sstrhex(string &str); bool strunquote(string &str);
uint strdec(const char *str); uint strhex(const char *str);
uint strdec(string &str); uint strhex(const string &str);
int sstrdec(const char *str); uint strdec(const char *str);
int sstrdec(string &str); uint strdec(const string &str);
uint strbin(const char *str); uint strbin(const char *str);
uint strbin(string &str); uint strbin(const string &str);
int sstrbin(const char *str); char *utoa(char *str, uint num);
int sstrbin(string &str);
char *utoa(char *str, uint num);
string &utoa(string &str, uint num); string &utoa(string &str, uint num);
char *itoa(char *str, uint num); char *itoa(char *str, uint num);
string &itoa(string &str, uint num); string &itoa(string &str, uint num);
char *htoa(char *str, uint num); char *htoa(char *str, uint num);
string &htoa(string &str, uint num); string &htoa(string &str, uint num);
char *uhtoa(char *str, uint num); char *btoa(char *str, uint num);
string &uhtoa(string &str, uint num);
char *btoa(char *str, uint num);
string &btoa(string &str, uint num); string &btoa(string &str, uint num);
bool strfread(string &str, const char *filename); bool strfread(string &str, const char *filename);
string strfmt(const char *fmt, int num); string strfmt(const char *fmt, int num);
int strmath(const char *in_str); int strmath(const char *str);
int strmath(string &in_str); int strmath(const string &str);
string &replace(string &str, const char *key, const char *token); string &replace(string &str, const char *key, const char *token);
string &replace(string &str, const char *key, string &token); string &replace(string &str, const char *key, const string &token);
string &qreplace(string &str, const char *key, const char *token); string &qreplace(string &str, const char *key, const char *token);
string &qreplace(string &str, const char *key, string &token); string &qreplace(string &str, const char *key, const string &token);
void split(stringarray &dest, const char *key, const char *src); void split(stringarray &dest, const char *key, const char *src);
void split(stringarray &dest, const char *key, string &src); void split(stringarray &dest, const char *key, const string &src);
void qsplit(stringarray &dest, const char *key, const char *src); void qsplit(stringarray &dest, const char *key, const char *src);
void qsplit(stringarray &dest, const char *key, string &src); void qsplit(stringarray &dest, const char *key, const string &src);
uint vsprintf(string &str, const char *s, va_list args); uint vsprintf(string &str, const char *s, va_list args);
uint sprintf(string &str, const char *s, ...); uint sprintf(string &str, const char *s, ...);
class string { class string {
public: public:
@ -184,7 +180,7 @@ uint size;
strcpy(s, str); strcpy(s, str);
} }
string(string &str) { string(const string &str) {
size = strlen(str); size = strlen(str);
s = (char*)malloc(size + 1); s = (char*)malloc(size + 1);
strcpy(s, strptr(str)); strcpy(s, strptr(str));
@ -193,33 +189,33 @@ uint size;
~string() { safe_free(s); } ~string() { safe_free(s); }
const char *operator()(); const char *operator()();
char &operator[](uint); char &operator[](const uint);
string &operator=(int); string &operator= (const int);
string &operator=(const char *); string &operator= (const char *);
string &operator=(string &); string &operator= (const string &);
string &operator+=(int); string &operator+=(const int);
string &operator+=(const char *); string &operator+=(const char *);
string &operator+=(string &); string &operator+=(const string &);
bool operator==(const char *); bool operator==(const char *);
bool operator==(string &); bool operator==(const string &);
bool operator!=(const char *); bool operator!=(const char *);
bool operator!=(string &); bool operator!=(const string &);
bool operator<(const char *); bool operator< (const char *);
bool operator<(string &); bool operator< (const string &);
bool operator<=(const char *); bool operator<=(const char *);
bool operator<=(string &); bool operator<=(const string &);
bool operator>(const char *); bool operator> (const char *);
bool operator>(string &); bool operator> (const string &);
bool operator>=(const char *); bool operator>=(const char *);
bool operator>=(string &); bool operator>=(const string &);
string operator+(int); string operator+(const int);
string operator+(const char *); string operator+(const char *);
string operator+(string &); string operator+(const string &);
}; };
string operator+(int, string &); string operator+(const int, const string &);
string operator+(const char *, string &); string operator+(const char *, const string &);
inline void swap(string &x, string &y) { x.swap(y); } inline void swap(string &x, string &y) { x.swap(y); }

View File

@ -110,12 +110,12 @@ int lhs = strmath_rdp(s, level + 1);
} }
#undef maxlevel #undef maxlevel
int strmath(const char *s) { int strmath(const char *str) {
return strmath_rdp(s); return strmath_rdp(str);
} }
#ifdef __LIBSTRING #ifdef __LIBSTRING
int strmath(string &s) { int strmath(const string &str) {
return strmath(strptr(s)); return strmath(strptr(str));
} }
#endif #endif

View File

@ -7,7 +7,7 @@ char &string::operator[](const uint index) {
return s[index]; return s[index];
} }
string &string::operator=(int num) { string &string::operator=(const int num) {
strcpy(*this, strfmt("%d", num)); strcpy(*this, strfmt("%d", num));
return *this; return *this;
} }
@ -17,12 +17,12 @@ string &string::operator=(const char *str) {
return *this; return *this;
} }
string &string::operator=(string &str) { string &string::operator=(const string &str) {
strcpy(*this, str); strcpy(*this, str);
return *this; return *this;
} }
string &string::operator+=(int num) { string &string::operator+=(const int num) {
strcat(*this, strfmt("%d", num)); strcat(*this, strfmt("%d", num));
return *this; return *this;
} }
@ -32,25 +32,25 @@ string &string::operator+=(const char *str) {
return *this; return *this;
} }
string &string::operator+=(string &str) { string &string::operator+=(const string &str) {
strcat(*this, str); strcat(*this, str);
return *this; return *this;
} }
bool string::operator==(const char *str) { return strcmp(strptr(*this), str) == 0; } bool string::operator==(const char *str) { return strcmp(strptr(*this), str) == 0; }
bool string::operator==(string &str) { return strcmp(strptr(*this), strptr(str)) == 0; } bool string::operator==(const string &str) { return strcmp(strptr(*this), strptr(str)) == 0; }
bool string::operator!=(const char *str) { return strcmp(strptr(*this), str) != 0; } bool string::operator!=(const char *str) { return strcmp(strptr(*this), str) != 0; }
bool string::operator!=(string &str) { return strcmp(strptr(*this), strptr(str)) != 0; } bool string::operator!=(const string &str) { return strcmp(strptr(*this), strptr(str)) != 0; }
bool string::operator<(const char *str) { return strcmp(strptr(*this), str) < 0; } bool string::operator< (const char *str) { return strcmp(strptr(*this), str) < 0; }
bool string::operator<(string &str) { return strcmp(strptr(*this), strptr(str)) < 0; } bool string::operator< (const string &str) { return strcmp(strptr(*this), strptr(str)) < 0; }
bool string::operator<=(const char *str) { return strcmp(strptr(*this), str) <= 0; } bool string::operator<=(const char *str) { return strcmp(strptr(*this), str) <= 0; }
bool string::operator<=(string &str) { return strcmp(strptr(*this), strptr(str)) <= 0; } bool string::operator<=(const string &str) { return strcmp(strptr(*this), strptr(str)) <= 0; }
bool string::operator>(const char *str) { return strcmp(strptr(*this), str) > 0; } bool string::operator> (const char *str) { return strcmp(strptr(*this), str) > 0; }
bool string::operator>(string &str) { return strcmp(strptr(*this), strptr(str)) > 0; } bool string::operator> (const string &str) { return strcmp(strptr(*this), strptr(str)) > 0; }
bool string::operator>=(const char *str) { return strcmp(strptr(*this), str) >= 0; } bool string::operator>=(const char *str) { return strcmp(strptr(*this), str) >= 0; }
bool string::operator>=(string &str) { return strcmp(strptr(*this), strptr(str)) >= 0; } bool string::operator>=(const string &str) { return strcmp(strptr(*this), strptr(str)) >= 0; }
string string::operator+(int num) { string string::operator+(const int num) {
string temp(*this); string temp(*this);
strcat(temp, strfmt("%d", num)); strcat(temp, strfmt("%d", num));
return temp; return temp;
@ -62,7 +62,7 @@ string temp(*this);
return temp; return temp;
} }
string string::operator+(string &str) { string string::operator+(const string &str) {
string temp(*this); string temp(*this);
strcat(temp, str); strcat(temp, str);
return temp; return temp;
@ -70,13 +70,13 @@ string temp(*this);
// //
string operator+(int x, string &y) { string operator+(const int x, const string &y) {
string temp(strfmt("%d", x)); string temp(strfmt("%d", x));
strcat(temp, y); strcat(temp, y);
return temp; return temp;
} }
string operator+(const char *x, string &y) { string operator+(const char *x, const string &y) {
string temp(x); string temp(x);
strcat(temp, y); strcat(temp, y);
return temp; return temp;

View File

@ -28,7 +28,7 @@ char *data;
free(data); free(data);
return str; return str;
} }
string &replace(string &str, const char *key, string &token) { return replace(str, key, strptr(token)); } string &replace(string &str, const char *key, const string &token) { return replace(str, key, strptr(token)); }
string &qreplace(string &str, const char *key, const char *token) { string &qreplace(string &str, const char *key, const char *token) {
int i, l, z, ksl = strlen(key), tsl = strlen(token), ssl = strlen(str); int i, l, z, ksl = strlen(key), tsl = strlen(token), ssl = strlen(str);
@ -83,4 +83,4 @@ char *data;
free(data); free(data);
return str; return str;
} }
string &qreplace(string &str, const char *key, string &token) { return qreplace(str, key, strptr(token)); } string &qreplace(string &str, const char *key, const string &token) { return qreplace(str, key, strptr(token)); }

View File

@ -12,7 +12,7 @@ int lp = 0, split_count = 0;
} }
strcpy(dest[split_count++], src + lp); strcpy(dest[split_count++], src + lp);
} }
void split(stringarray &dest, const char *key, string &src) { split(dest, key, strptr(src)); } void split(stringarray &dest, const char *key, const string &src) { split(dest, key, strptr(src)); }
void qsplit(stringarray &dest, const char *key, const char *src) { void qsplit(stringarray &dest, const char *key, const char *src) {
dest.reset(); dest.reset();
@ -34,4 +34,4 @@ int lp = 0, split_count = 0;
} }
strcpy(dest[split_count++], src + lp); strcpy(dest[split_count++], src + lp);
} }
void qsplit(stringarray &dest, const char *key, string &src) { qsplit(dest, key, strptr(src)); } void qsplit(stringarray &dest, const char *key, const string &src) { qsplit(dest, key, strptr(src)); }

82
src/lib/libtuple.h Normal file
View File

@ -0,0 +1,82 @@
/*
libtuple : version 0.01 ~byuu (2007-01-04)
dependencies:
- libbase
*/
#ifndef __LIBTUPLE
#define __LIBTUPLE
/*****
* tuple definitions
*****/
template<
typename = null_t, typename = null_t, typename = null_t, typename = null_t,
typename = null_t, typename = null_t, typename = null_t, typename = null_t
> struct tuple;
template<int, typename> struct tuple_traits;
/*****
* tuple_traits
*****/
#define make_tuple_traits(n) \
template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7> \
struct tuple_traits< n, tuple<T0, T1, T2, T3, T4, T5, T6, T7> > { \
typedef T##n type; \
static inline T##n &get(tuple<T0, T1, T2, T3, T4, T5, T6, T7> &t) { return t.t##n; } \
};
make_tuple_traits(0)
make_tuple_traits(1)
make_tuple_traits(2)
make_tuple_traits(3)
make_tuple_traits(4)
make_tuple_traits(5)
make_tuple_traits(6)
make_tuple_traits(7)
#undef make_tuple_traits
/*****
* tuple
*****/
template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
struct tuple {
T0 t0;
T1 t1;
T2 t2;
T3 t3;
T4 t4;
T5 t5;
T6 t6;
T7 t7;
template<int index>
typename tuple_traits<index, tuple>::type &get() {
return tuple_traits<index, tuple>::get(*this);
}
bool operator==(const tuple &source) {
return (t0 == source.t0 && t1 == source.t1 && t2 == source.t2 && t3 == source.t3 &&
t4 == source.t4 && t5 == source.t5 && t6 == source.t6 && t7 == source.t7);
}
bool operator!=(const tuple &source) {
return (t0 != source.t0 && t1 != source.t1 && t2 != source.t2 && t3 != source.t3 &&
t4 != source.t4 && t5 != source.t5 && t6 != source.t6 && t7 != source.t7);
}
tuple(const tuple &t) { operator=(t); }
tuple(const T0 &_t0 = T0(), const T1 &_t1 = T1(), const T2 &_t2 = T2(), const T3 &_t3 = T3(),
const T4 &_t4 = T4(), const T5 &_t5 = T5(), const T6 &_t6 = T6(), const T7 &_t7 = T7()) :
t0(_t0), t1(_t1), t2(_t2), t3(_t3), t4(_t4), t5(_t5), t6(_t6), t7(_t7) {}
};
template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5, typename T6, typename T7>
tuple<T0, T1, T2, T3, T4, T5, T6, T7> make_tuple(
const T0 &t0 = T0(), const T1 &t1 = T1(), const T2 &t2 = T2(), const T3 &t3 = T3(),
const T4 &t4 = T4(), const T5 &t5 = T5(), const T6 &t6 = T6(), const T7 &t7 = T7()) {
return tuple<T0, T1, T2, T3, T4, T5, T6, T7>(t0, t1, t2, t3, t4, t5, t6, t7);
}
#endif

39
src/lib/libui_gtk.cpp Normal file
View File

@ -0,0 +1,39 @@
#include "libui_gtk.h"
#include "libui_gtk_window.cpp"
#include "libui_gtk_control.cpp"
namespace libui {
void init() {
int argc = 1;
char **argv;
argv = (char**)malloc(1 * sizeof(char*));
argv[0] = (char*)malloc(64 * sizeof(char));
strcpy(argv[0], "./libui");
//GTK+ insists you provide main()'s argc, argv parameters for
//some special command-line processing options that are likely
//never used by anything.
//However, I insist on libui_init() not requiring arguments so
//that it can be called from anywhere, including a global
//constructor that is invoked before main() is reached.
gtk_init(&argc, &argv);
safe_free(argv[0]);
safe_free(argv);
}
void term() {
}
bool run() {
gtk_main_iteration_do(false);
return events_pending();
}
bool events_pending() {
return gtk_events_pending();
}
uint get_screen_width() { return gdk_screen_width(); }
uint get_screen_height() { return gdk_screen_height(); }
};

72
src/lib/libui_gtk.h Normal file
View File

@ -0,0 +1,72 @@
/*
libui_gtk ~byuu (2007-01-29)
*/
#ifndef __LIBUI
#define __LIBUI
#include <gtk/gtk.h>
#include <gdk/gdkx.h>
namespace libui {
void init();
void term();
bool run();
bool events_pending();
uint get_screen_width();
uint get_screen_height();
class Window;
typedef unsigned long WindowHandle;
#include "libui_gtk_control.h"
class Window { public:
struct {
GtkWidget *window;
GtkWidget *vcontainer, *container;
array<Control*> control;
uint control_index;
bool has_menu;
array<MenuGroup*> menu_group;
uint menu_group_index;
} info;
WindowHandle handle();
void create(const char *style, uint width, uint height, const char *caption = "");
void focus();
void move(uint x, uint y);
void resize(uint width, uint height);
virtual void show();
virtual void hide();
virtual bool close() { return true; }
virtual void keydown(uint key) {}
virtual void keyup(uint key) {}
void set_background_color(uint8 r, uint8 g, uint8 b);
bool file_load(char *filename, const char *filter, const char *path = "");
bool file_save(char *filename, const char *filter, const char *path = "");
void menu_begin();
void menu_end();
void menu_group_begin(MenuGroup &group);
void menu_group_end();
void menu_add_item(Control &item);
void menu_add_separator();
void attach(Control &control, uint x, uint y, bool attach_to_window = true);
virtual void clicked(Control*) {}
Window() {
info.control_index = 1;
info.has_menu = false;
info.menu_group_index = 1;
}
};
};
#endif

View File

@ -0,0 +1,634 @@
namespace libui {
/*****
* FileLoad
*****/
bool Window::file_load(char *filename, const char *filter, const char *path) {
strcpy(filename, "");
GtkWidget *dialog = gtk_file_chooser_dialog_new("Load File",
GTK_WINDOW(info.window), GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT, 0);
if(path && strcmp(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 != ""
}
/*****
* FileSave
*****/
bool Window::file_save(char *filename, const char *filter, const char *path) {
strcpy(filename, "");
GtkWidget *dialog = gtk_file_chooser_dialog_new("Save File",
GTK_WINDOW(info.window), GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, 0);
if(path && strcmp(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 != ""
}
/*****
* Control
*****/
void Control::move(uint x, uint y) {
gtk_fixed_move(GTK_FIXED(owner->info.container), widget, x, y);
}
void Control::resize(uint width, uint height) {
gtk_widget_set_size_request(widget, width, height);
}
void Control::show() {
gtk_widget_show(widget);
}
void Control::hide() {
gtk_widget_hide(widget);
}
void Control::show(bool state) {
(state == true) ? show() : hide();
}
bool Control::visible() {
return GTK_WIDGET_VISIBLE(widget);
}
void Control::enable() {
gtk_widget_set_sensitive(widget, true);
}
void Control::disable() {
gtk_widget_set_sensitive(widget, false);
}
void Control::enable(bool state) {
(state == true) ? enable() : disable();
}
bool Control::enabled() {
return GTK_WIDGET_SENSITIVE(widget);
}
/*****
* Menu
*****/
void Window::menu_begin() {}
void Window::menu_end() {}
/*****
* Menu
*****/
void Window::menu_group_begin(MenuGroup &group) {
info.control[info.control_index] = &group;
group.id = info.control_index++;
group.owner = this;
info.menu_group[++info.menu_group_index] = &group;
}
void Window::menu_group_end() {
MenuGroup *group = info.menu_group[info.menu_group_index--];
MenuGroup *owner = info.menu_group[info.menu_group_index];
gtk_menu_item_set_submenu(GTK_MENU_ITEM(group->item), group->widget);
gtk_menu_bar_append(owner->widget, group->item);
gtk_widget_show(group->item);
}
void Window::menu_add_item(Control &item) {
info.control[info.control_index] = &item;
MenuGroup &group = *info.menu_group[info.menu_group_index];
item.id = info.control_index++;
item.owner = this;
gtk_menu_shell_append(GTK_MENU_SHELL(group.widget), item.widget);
g_signal_connect_swapped(G_OBJECT(item.widget), "activate",
G_CALLBACK(libui_control_clicked), (gpointer)&item);
}
void Window::menu_add_separator() {
MenuItem *item = new MenuItem();
info.control[info.control_index] = item;
MenuGroup *group = info.menu_group[info.menu_group_index];
item->id = info.control_index++;
item->owner = this;
item->type = Control::MenuItem;
item->widget = gtk_separator_menu_item_new();
gtk_menu_shell_append(GTK_MENU_SHELL(group->widget), item->widget);
gtk_widget_show(item->widget);
}
/*****
* MenuGroup
*****/
MenuGroup& MenuGroup::create(const char *caption) {
type = Control::MenuGroup;
widget = gtk_menu_new();
item = gtk_menu_item_new_with_label(caption ? caption : "?");
return *this;
}
/*****
* MenuItem
*****/
MenuItem& MenuItem::create(const char *caption) {
type = Control::MenuItem;
widget = gtk_menu_item_new_with_label(caption ? caption : "?");
gtk_widget_show(widget);
return *this;
}
/*****
* MenuCheckItem
*****/
MenuCheckItem& MenuCheckItem::create(const char *caption) {
type = Control::MenuCheckItem;
widget = gtk_check_menu_item_new_with_label(caption ? caption : "?");
gtk_widget_show(widget);
return *this;
}
void MenuCheckItem::check() {
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), TRUE);
}
void MenuCheckItem::uncheck() {
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), FALSE);
}
void MenuCheckItem::check(bool state) {
(state == true) ? check() : uncheck();
}
bool MenuCheckItem::checked() {
return gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
}
/*****
* MenuRadioItem
*****/
MenuRadioItem& MenuRadioItem::create(ControlGroup &list, const char *caption) {
if(list.count() == 0)throw;
type = Control::MenuRadioItem;
widget = (&list[0] == this) ?
gtk_radio_menu_item_new_with_label(0, caption ? caption : "?") :
gtk_radio_menu_item_new_with_label_from_widget(GTK_RADIO_MENU_ITEM(list[0].widget), caption ? caption : "");
gtk_widget_show(widget);
return *this;
}
void MenuRadioItem::check() {
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), TRUE);
}
bool MenuRadioItem::checked() {
return gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
}
/*****
* Container
*****/
Container &Container::create(const char *style, uint width, uint height) {
type = Control::Container;
widget = gtk_fixed_new();
gtk_widget_set_size_request(widget, width, height);
gtk_widget_show(widget);
return *this;
}
void Container::attach(Control &control, uint x, uint y) {
owner->attach(control, x, y, false);
gtk_fixed_put(GTK_FIXED(widget), control.widget, x, y);
}
/*****
* Canvas
*****/
Canvas &Canvas::create(const char *style, uint width, uint height) {
type = Control::Canvas;
widget = gtk_drawing_area_new();
gtk_widget_set_size_request(widget, width, height);
gtk_widget_show(widget);
return *this;
}
WindowHandle Canvas::handle() {
return (WindowHandle)(GDK_WINDOW_XWINDOW(widget->window));
}
void Canvas::set_background_color(uint8 r, uint8 g, uint8 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(widget, GTK_STATE_NORMAL, &color);
}
/*****
* Frame
*****/
Frame& Frame::create(const char *style, uint width, uint height, const char *caption) {
type = Control::Frame;
widget = gtk_frame_new(caption ? caption : "");
gtk_widget_set_size_request(widget, width, height);
gtk_widget_show(widget);
return *this;
}
/*****
* Label
*****/
Label& Label::create(const char *style, uint width, uint height, const char *caption) {
type = Control::Label;
widget = gtk_label_new(caption ? caption : "");
gtk_misc_set_alignment(GTK_MISC(widget), 0.0, 0.0);
gtk_widget_set_size_request(widget, width, height);
gtk_widget_show(widget);
return *this;
}
void Label::set_text(const char *str, ...) {
va_list args;
va_start(args, str);
string temp;
vsprintf(temp, str, args);
va_end(args);
gtk_label_set_label(GTK_LABEL(widget), strptr(temp));
}
uint Label::get_text(char *str, uint length) {
const char *temp = gtk_label_get_text(GTK_LABEL(widget));
return strlcpy(str, temp ? temp : "", length);
}
/*****
* Button
*****/
Button& Button::create(const char *style, uint width, uint height, const char *caption) {
type = Control::Button;
widget = gtk_button_new_with_label(caption ? caption : "");
gtk_widget_set_size_request(widget, width, height);
gtk_widget_show(widget);
return *this;
}
void Button::set_text(const char *str, ...) {
va_list args;
va_start(args, str);
string temp;
vsprintf(temp, str, args);
va_end(args);
gtk_button_set_label(GTK_BUTTON(widget), strptr(temp));
}
uint Button::get_text(char *str, uint length) {
const char *temp = gtk_button_get_label(GTK_BUTTON(widget));
return strlcpy(str, temp ? temp : "", length);
}
/*****
* Checkbox
*****/
Checkbox& Checkbox::create(const char *style, uint width, uint height, const char *caption) {
type = Control::Checkbox;
widget = gtk_check_button_new_with_label(caption ? caption : "");
gtk_widget_set_size_request(widget, width, height);
gtk_widget_show(widget);
return *this;
}
void Checkbox::check() {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
}
void Checkbox::uncheck() {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), FALSE);
}
void Checkbox::check(bool state) {
(state == true) ? check() : uncheck();
}
bool Checkbox::checked() {
return (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) == TRUE) ? true : false;
}
/*****
* Radiobox
*****/
Radiobox& Radiobox::create(ControlGroup &group, const char *style, uint width, uint height, const char *caption) {
if(group.count() == 0)throw;
type = Control::Radiobox;
widget = (&group[0] == this) ?
gtk_radio_button_new_with_label(0, caption ? caption : "") :
gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(group[0].widget), caption ? caption : "");
gtk_widget_set_size_request(widget, width, height);
gtk_widget_show(widget);
return *this;
}
void Radiobox::check() {
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
}
bool Radiobox::checked() {
return (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)) == TRUE) ? true : false;
}
/*****
* Editbox
*****/
Editbox& Editbox::create(const char *style, uint width, uint height, const char *caption) {
type = Control::Editbox;
multiline = false;
stringarray part;
split(part, "|", style);
for(uint i = 0; i < count(part); i++) {
if(part[i] == "multiline")multiline = true;
}
if(multiline == false) {
widget = gtk_entry_new();
gtk_entry_set_text(GTK_ENTRY(widget), caption ? caption : "");
} else {
widget = gtk_text_view_new();
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
gtk_text_buffer_set_text(buffer, caption ? caption : "", -1);
}
gtk_widget_set_size_request(widget, width, height);
gtk_widget_show(widget);
return *this;
}
void Editbox::set_text(const char *str, ...) {
va_list args;
va_start(args, str);
string temp;
vsprintf(temp, str, args);
va_end(args);
if(multiline == false) {
gtk_entry_set_text(GTK_ENTRY(widget), strptr(temp));
} else {
gtk_text_buffer_set_text(buffer, strptr(temp), -1);
}
}
uint Editbox::get_text(char *str, uint length) {
if(multiline == false) {
const char *temp = gtk_entry_get_text(GTK_ENTRY(widget));
return strlcpy(str, temp ? temp : "", length);
} else {
//not sure how to use GtkTextIter* to retrieve editbox text buffer ...
strcpy(str, "");
return 0;
}
}
/*****
* Listbox
*****/
/*****
* GTK+'s implementation of list boxes was apparently someone's idea of a very, very cruel joke ...
* Attempt to understand the below code at the risk of your own sanity.
*****/
Listbox& Listbox::create(const char *style, uint width, uint height, const char *columns, const char *data) {
type = Control::Listbox;
stringarray list, part;
split(part, "|", style);
bool header = false;
for(uint i = 0; i < count(part); i++) {
if(part[i] == "header")header = true;
}
split(part, "|", columns);
GType *v = (GType*)malloc(count(part) * sizeof(GType));
for(uint i = 0; i < count(part); i++) { v[i] = G_TYPE_STRING; }
store = gtk_list_store_newv(count(part), v);
safe_free(v);
if(data && strcmp(data, "")) {
split(list, "||", data);
for(uint l = 0; l < count(list); l++) {
gtk_list_store_append(store, &iter);
split(part, "|", list[l]);
for(uint i = 0; i < count(part); i++) {
gtk_list_store_set(store, &iter, i, strptr(part[i]), -1);
}
}
}
widget = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
g_object_unref(G_OBJECT(store));
gtk_widget_set_size_request(widget, width, height);
gtk_widget_show(widget);
split(list, "|", columns);
for(uint i = 0; i < count(list); i++) {
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes(strptr(list[i]), renderer, "text", i, 0);
column_list[column_list.size()] = column;
gtk_tree_view_append_column(GTK_TREE_VIEW(widget), column);
}
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(widget), header);
autosize_columns();
return *this;
}
void Listbox::autosize_columns() {
gtk_tree_view_columns_autosize(GTK_TREE_VIEW(widget));
}
void Listbox::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 Listbox::add_item(const char *data) {
stringarray part;
split(part, "|", data);
gtk_list_store_append(store, &iter);
for(uint i = 0; i < count(part); i++) {
gtk_list_store_set(store, &iter, i, strptr(part[i]), -1);
}
}
int Listbox::get_selection() {
//... because gtk_tree_view_get_selected_row(GTK_TREE_VIEW(widget)) would be too easy ...
GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(widget));
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 Listbox::set_selection(int index) {
//... because gtk_tree_view_set_selected_row(GTK_TREE_VIEW(widget), index) would be too easy ...
GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(widget));
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(widget));
gtk_tree_selection_unselect_all(selection);
if(index < 0) { return; }
if(gtk_tree_model_get_iter_first(model, &iter) == false) { return; }
if(index == 0) { gtk_tree_selection_select_iter(selection, &iter); return; }
for(uint i = 1; i < 100000; i++) {
if(gtk_tree_model_iter_next(model, &iter) == false) { return; }
if(index == i) { gtk_tree_selection_select_iter(selection, &iter); return; }
}
}
void Listbox::reset() {
gtk_list_store_clear(GTK_LIST_STORE(store));
gtk_tree_view_set_model(GTK_TREE_VIEW(widget), GTK_TREE_MODEL(store));
}
/*****
* Combobox
*****/
Combobox& Combobox::create(const char *style, uint width, uint height, const char *data) {
type = Control::Combobox;
widget = gtk_combo_box_new_text(); //gtk_combo_box_entry_new_text();
counter = 0;
gtk_widget_set_size_request(widget, width, height);
gtk_widget_show(widget);
if(data && strcmp(data, "")) {
stringarray temp;
split(temp, "|", data);
for(int i = 0; i < count(temp); i++) {
gtk_combo_box_append_text(GTK_COMBO_BOX(widget), strptr(temp[i]));
counter++;
}
set_selection(0);
}
return *this;
}
void Combobox::add_item(const char *data) {
gtk_combo_box_append_text(GTK_COMBO_BOX(widget), data);
if(counter++ == 0) { set_selection(0); }
}
int Combobox::get_selection() {
return gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
}
void Combobox::set_selection(int index) {
gtk_combo_box_set_active(GTK_COMBO_BOX(widget), index);
}
void Combobox::reset() {
if(counter == 0) { return; }
for(int i = (counter - 1); i >= 0; i--) {
gtk_combo_box_remove_text(GTK_COMBO_BOX(widget), i);
}
counter = 0;
}
/*****
* Progressbar
*****/
Progressbar& Progressbar::create(const char *style, uint width, uint height) {
type = Control::Progressbar;
widget = gtk_progress_bar_new();
gtk_widget_set_size_request(widget, width, height);
gtk_widget_show(widget);
return *this;
}
void Progressbar::set_progress(uint progress) {
progress = minmax<0, 100>(progress);
double p = (double)progress / 100.0;
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(widget), p);
}
uint Progressbar::get_progress() {
uint p = (uint)(gtk_progress_bar_get_fraction(GTK_PROGRESS_BAR(widget)) * 100.0);
return (uint)minmax<0, 100>(p);
}
/*****
* Slider
*****/
Slider& Slider::create(const char *style, uint width, uint height, uint min, uint max) {
type = Control::Slider;
orientation = 0;
stringarray part;
split(part, "|", style);
for(uint i = 0; i < count(part); i++) {
if(part[i] == "horizontal")orientation = 0;
if(part[i] == "vertical")orientation = 1;
}
if(orientation == 0) {
widget = gtk_hscale_new_with_range(min, max, 1);
} else {
widget = gtk_vscale_new_with_range(min, max, 1);
}
gtk_scale_set_draw_value(GTK_SCALE(widget), FALSE);
gtk_widget_set_size_request(widget, width, height);
gtk_widget_show(widget);
return *this;
}
void Slider::set_position(uint position) {
gtk_range_set_value(GTK_RANGE(widget), position);
}
uint Slider::get_position() {
return (int)gtk_range_get_value(GTK_RANGE(widget));
}
};

146
src/lib/libui_gtk_control.h Normal file
View File

@ -0,0 +1,146 @@
class Control { public:
Window *owner;
GtkWidget *widget;
uint id;
uint type;
enum {
Invalid,
MenuGroup,
MenuItem,
MenuCheckItem,
MenuRadioItem,
Container,
Canvas,
Frame,
Label,
Button,
Checkbox,
Radiobox,
Editbox,
Listbox,
Combobox,
Progressbar,
Slider,
};
void move(uint x, uint y);
void resize(uint width, uint height);
void show();
void hide();
void show(bool state);
bool visible();
void enable();
void disable();
void enable(bool state);
bool enabled();
Control() : owner(0), widget(0), id(0), type(Invalid) {}
};
class ControlGroup { public:
array<Control*> list;
uint count() { return list.size(); }
void add(Control &control) { list[list.size()] = &control; }
void reset() { list.reset(); }
ControlGroup &operator=(ControlGroup &source) { list = source.list; return *this; }
Control &operator[](int index) { return *list[index]; }
};
class MenuGroup : public Control { public:
bool master;
GtkWidget *item;
MenuGroup &create(const char *caption);
MenuGroup() : master(false) {}
};
class MenuItem : public Control { public:
MenuItem &create(const char *caption);
};
class MenuCheckItem : public Control { public:
MenuCheckItem &create(const char *caption);
void check();
void uncheck();
void check(bool state);
bool checked();
};
class MenuRadioItem : public Control { public:
MenuRadioItem &create(ControlGroup &list, const char *caption);
void check();
bool checked();
};
class Container : public Control { public:
Container &create(const char *style, uint width, uint height);
void attach(Control &control, uint x, uint y);
};
class Canvas : public Control { public:
Canvas &create(const char *style, uint width, uint height);
WindowHandle handle();
void set_background_color(uint8 r, uint8 g, uint8 b);
};
class Frame : public Control { public:
Frame &create(const char *style, uint width, uint height, const char *caption = "");
};
class Label : public Control { public:
Label &create(const char *style, uint width, uint height, const char *caption = "");
void set_text(const char *str, ...);
uint get_text(char *str, uint length);
};
class Button : public Control { public:
Button &create(const char *style, uint width, uint height, const char *caption = "");
void set_text(const char *str, ...);
uint get_text(char *str, uint length);
};
class Checkbox : public Control { public:
Checkbox &create(const char *style, uint width, uint height, const char *caption = "");
void check();
void uncheck();
void check(bool state);
bool checked();
};
class Radiobox : public Control { public:
Radiobox &create(ControlGroup &group, const char *style, uint width, uint height, const char *caption = "");
void check();
bool checked();
};
class Editbox : public Control { public:
GtkTextBuffer *buffer;
bool multiline;
Editbox &create(const char *style, uint width, uint height, const char *caption = "");
void set_text(const char *str, ...);
uint get_text(char *str, uint length);
};
class Listbox : public Control { public:
GtkListStore *store;
GtkCellRenderer *renderer;
GtkTreeViewColumn *column;
array<GtkTreeViewColumn*> column_list;
GtkTreeIter iter;
Listbox &create(const char *style, uint width, uint height, const char *columns = "", const char *data = "");
void autosize_columns();
void set_column_width(uint column, uint width);
void add_item(const char *data);
int get_selection();
void set_selection(int index);
void reset();
};
class Combobox : public Control { public:
uint counter;
Combobox &create(const char *style, uint width, uint height, const char *caption = "");
void add_item(const char *data);
int get_selection();
void set_selection(int index);
void reset();
};
class Progressbar : public Control { public:
Progressbar &create(const char *style, uint width, uint height);
void set_progress(uint progress);
uint get_progress();
};
class Slider : public Control { public:
bool orientation;
Slider &create(const char *style, uint width, uint height, uint min, uint max);
void set_position(uint position);
uint get_position();
};

View File

@ -0,0 +1,118 @@
namespace libui {
gint libui_window_close(GtkWidget *w, GdkEventAny *any, Window *window) {
if(window) { return !window->close(); }
return FALSE; //destroy window by default
}
gint libui_window_keydown(GtkWidget *w, GdkEventKey *key, Window *window) {
if(window) { window->keydown(key->keyval); }
return FALSE;
}
gint libui_window_keyup(GtkWidget *w, GdkEventKey *key, Window *window) {
if(window) { window->keyup(key->keyval); }
return FALSE;
}
void libui_control_clicked(Control *control) {
if(control && control->owner) { control->owner->clicked(control); }
}
WindowHandle Window::handle() {
return (WindowHandle)(GDK_WINDOW_XWINDOW(info.window->window));
}
void Window::attach(Control &control, uint x, uint y, bool attach_to_window) {
info.control[info.control_index] = &control;
control.id = info.control_index++;
control.owner = this;
if(attach_to_window == true) {
gtk_fixed_put(GTK_FIXED(info.container), control.widget, x, y);
}
switch(control.type) {
case Control::Button:
case Control::Checkbox:
case Control::Radiobox: {
g_signal_connect_swapped(G_OBJECT(control.widget), "clicked",
G_CALLBACK(libui_control_clicked), (gpointer)&control);
} break;
}
}
void Window::create(const char *style, uint width, uint height, const char *caption) {
info.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(info.window), caption ? caption : "");
gtk_window_set_resizable(GTK_WINDOW(info.window), false);
g_signal_connect(G_OBJECT(info.window), "delete_event", G_CALLBACK(libui_window_close), (gpointer)this);
g_signal_connect(G_OBJECT(info.window), "key_press_event", G_CALLBACK(libui_window_keydown), (gpointer)this);
g_signal_connect(G_OBJECT(info.window), "key_release_event", G_CALLBACK(libui_window_keyup), (gpointer)this);
stringarray part;
split(part, "|", style);
for(int i = 0; i < count(part); i++) {
if(part[i] == "menu") { info.has_menu = true; }
if(part[i] == "center") { gtk_window_set_position(GTK_WINDOW(info.window), GTK_WIN_POS_CENTER_ALWAYS); }
}
info.vcontainer = gtk_vbox_new(false, 0);
gtk_container_add(GTK_CONTAINER(info.window), info.vcontainer);
gtk_widget_show(info.vcontainer);
if(info.has_menu == true) {
MenuGroup *group = new MenuGroup();
info.control[info.control_index] = group;
group->id = info.control_index++;
group->owner = this;
group->type = Control::MenuGroup;
group->master = true;
group->widget = gtk_menu_bar_new();
gtk_box_pack_start(GTK_BOX(info.vcontainer), group->widget, false, false, 0);
gtk_widget_show(group->widget);
info.menu_group[++info.menu_group_index] = group;
}
info.container = gtk_fixed_new();
gtk_widget_set_size_request(info.container, width, height);
gtk_box_pack_end(GTK_BOX(info.vcontainer), info.container, true, true, 0);
gtk_widget_show(info.container);
}
void Window::focus() {
gtk_window_present(GTK_WINDOW(info.window));
}
void Window::move(uint x, uint y) {
//if window was centered before, GTK+ will ignore move requests,
//therfore we must turn off auto-centering.
gtk_window_set_position(GTK_WINDOW(info.window), GTK_WIN_POS_NONE);
gtk_window_move(GTK_WINDOW(info.window), x, y);
}
void Window::resize(uint width, uint height) {
gtk_widget_set_size_request(info.container, width, height);
}
void Window::show() {
gtk_widget_show(info.window);
}
void Window::hide() {
gtk_widget_hide(info.window);
}
void Window::set_background_color(uint8 r, uint8 g, uint8 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(info.window, GTK_STATE_NORMAL, &color);
}
};

59
src/lib/libui_win.cpp Normal file
View File

@ -0,0 +1,59 @@
#include "libui_win.h"
#include "libui_win_window.cpp"
#include "libui_win_control.cpp"
namespace libui {
HFONT 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;
}
void init() {
InitCommonControls();
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 = libui_wndproc;
wc.lpszClassName = "libui_class";
wc.lpszMenuName = 0;
wc.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wc);
message_window = CreateWindow("libui_class", "", WS_POPUP,
0, 0, 64, 64, 0, 0, GetModuleHandle(0), 0);
SetWindowLongPtr(message_window, GWLP_USERDATA, 0);
font.variable = create_font("Tahoma", 8);
font.fixed = create_font("Courier New", 8);
}
void term() {
}
bool run() {
MSG msg;
if(PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return events_pending();
}
bool events_pending() {
MSG msg;
return PeekMessage(&msg, 0, 0, 0, PM_NOREMOVE);
}
uint get_screen_width() { return GetSystemMetrics(SM_CXSCREEN); }
uint get_screen_height() { return GetSystemMetrics(SM_CYSCREEN); }
};

90
src/lib/libui_win.h Normal file
View File

@ -0,0 +1,90 @@
/*
libui_win ~byuu (2006-01-29)
*/
#ifndef __LIBUI
#define __LIBUI
#define WINVER 0x0500
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <commctrl.h>
namespace libui {
void init();
void term();
bool run();
bool events_pending();
uint get_screen_width();
uint get_screen_height();
class Window;
typedef HWND WindowHandle;
#include "libui_win_control.h"
class Window { public:
struct {
uint width, height;
HWND hwnd;
HWND hwnd_resize;
HBRUSH background;
bool center;
array<Control*> control;
uint control_index;
bool has_menu;
MenuGroup menu_owner;
array<MenuGroup*> menu_group;
uint menu_group_index;
array<MenuRadioItem*> menu_check_list;
} info;
long wndproc(HWND hwnd, uint msg, WPARAM wparam, LPARAM lparam);
WindowHandle handle();
void create(const char *style, uint width, uint height, const char *caption);
void focus();
void move(uint x, uint y);
void resize(uint width, uint height);
virtual void show();
virtual void hide();
virtual bool close() { return true; }
virtual void keydown(uint key) {}
virtual void keyup(uint key) {}
void set_background_color(uint8 r, uint8 g, uint8 b);
bool file_load(char *filename, const char *filter, const char *path = "");
bool file_save(char *filename, const char *filter, const char *path = "");
void menu_begin();
void menu_end();
void menu_group_begin(MenuGroup &group);
void menu_group_end();
void menu_add_item(Control &item);
void menu_add_separator();
void move(Control &control, uint x, uint y);
void attach(Control &control, uint x, uint y, bool attach_to_window = true);
virtual void clicked(Control*) {}
Window();
};
//platform dependent
static uint window_count = 0;
HFONT create_font(const char *name, uint size);
HWND message_window;
struct {
HFONT variable;
HFONT fixed;
} font;
};
#endif

View File

@ -0,0 +1,630 @@
namespace libui {
/*****
* FileLoad
*****/
bool Window::file_load(char *filename, const char *filter, const char *path) {
string dir, f;
strcpy(dir, path ? path : "");
replace(dir, "/", "\\");
stringarray 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 = strptr(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 = info.hwnd;
ofn.lpstrFilter = pf;
ofn.lpstrInitialDir = strptr(dir);
ofn.lpstrFile = filename;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST;
ofn.lpstrDefExt = "";
return GetOpenFileName(&ofn);
}
/*****
* FileSave
*****/
bool Window::file_save(char *filename, const char *filter, const char *path) {
string dir, f;
strcpy(dir, path ? path : "");
replace(dir, "/", "\\");
stringarray 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 = strptr(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 = info.hwnd;
ofn.lpstrFilter = pf;
ofn.lpstrInitialDir = strptr(dir);
ofn.lpstrFile = filename;
ofn.nMaxFile = MAX_PATH;
ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST;
ofn.lpstrDefExt = "";
return GetSaveFileName(&ofn);
}
/*****
* Control
*****/
void Control::resize(uint width, uint height) {
SetWindowPos(hwnd, 0, 0, 0, width, height, SWP_NOZORDER | SWP_NOMOVE);
}
void Control::show() {
ShowWindow(hwnd, SW_NORMAL);
}
void Control::hide() {
ShowWindow(hwnd, SW_HIDE);
}
void Control::show(bool state) {
(state == true) ? show() : hide();
}
bool Control::visible() {
return (GetWindowLong(hwnd, GWL_STYLE) & WS_VISIBLE) ? true : false;
}
void Control::enable() {
EnableWindow(hwnd, true);
}
void Control::disable() {
EnableWindow(hwnd, false);
}
void Control::enable(bool state) {
(state == true) ? enable() : disable();
}
bool Control::enabled() {
return !(GetWindowLong(hwnd, GWL_STYLE) & WS_DISABLED);
}
/*****
* Menu
*****/
void Window::menu_begin() {
info.menu_check_list.reset();
}
void Window::menu_end() {
SetMenu(info.hwnd_resize, info.menu_owner.group);
SetMenu(info.hwnd, info.menu_owner.group);
resize(info.width, info.height);
//check all menu radio items that need to be ...
for(uint i = 0; i < info.menu_check_list.size(); i++) {
info.menu_check_list[i]->check();
}
info.menu_check_list.reset();
}
void Window::menu_group_begin(MenuGroup &group) {
info.control[info.control_index] = &group;
group.id = info.control_index++;
group.owner = this;
info.menu_group[++info.menu_group_index] = &group;
}
void Window::menu_group_end() {
MenuGroup *group = info.menu_group[info.menu_group_index--];
MenuGroup *owner = info.menu_group[info.menu_group_index];
AppendMenu(owner->group, MF_STRING | MF_POPUP, (uint)group->group, group->caption);
}
void Window::menu_add_item(Control &item) {
info.control[info.control_index] = &item;
MenuGroup *group = info.menu_group[info.menu_group_index];
item.id = info.control_index++;
item.owner = this;
switch(item.type) {
case Control::MenuItem: {
AppendMenu(group->group, MF_STRING, (uint)item.id, static_cast<MenuItem&>(item).caption);
} break;
case Control::MenuCheckItem: {
AppendMenu(group->group, MF_STRING, (uint)item.id, static_cast<MenuCheckItem&>(item).caption);
} break;
case Control::MenuRadioItem: {
AppendMenu(group->group, MF_STRING, (uint)item.id, static_cast<MenuRadioItem&>(item).caption);
MenuRadioItem &radio = static_cast<MenuRadioItem&>(item);
if(&radio == &radio.group[0]) { info.menu_check_list[info.menu_check_list.size()] = &radio; }
} break;
};
}
void Window::menu_add_separator() {
MenuGroup *group = info.menu_group[info.menu_group_index];
AppendMenu(group->group, MF_SEPARATOR, 0, "");
}
/*****
* MenuGroup
*****/
MenuGroup& MenuGroup::create(const char *_caption) {
type = Control::MenuGroup;
group = CreatePopupMenu();
caption = strdup(_caption);
return *this;
}
/*****
* MenuItem
*****/
MenuItem& MenuItem::create(const char *_caption) {
type = Control::MenuItem;
caption = strdup(_caption);
return *this;
}
/*****
* MenuCheckItem
*****/
MenuCheckItem& MenuCheckItem::create(const char *_caption) {
type = Control::MenuCheckItem;
caption = strdup(_caption);
return *this;
}
void MenuCheckItem::check() {
CheckMenuItem(owner->info.menu_owner.group, id, MF_CHECKED);
}
void MenuCheckItem::uncheck() {
CheckMenuItem(owner->info.menu_owner.group, id, MF_UNCHECKED);
}
void MenuCheckItem::check(bool state) {
(state == true) ? check() : uncheck();
}
bool MenuCheckItem::checked() {
MENUITEMINFO info;
memset(&info, 0, sizeof(info));
info.cbSize = sizeof(info);
info.fMask = MIIM_STATE;
GetMenuItemInfo(owner->info.menu_owner.group, id, false, &info);
return (info.fState & MFS_CHECKED);
}
/*****
* MenuRadioItem
*****/
MenuRadioItem& MenuRadioItem::create(ControlGroup &list, const char *_caption) {
if(list.count() == 0)throw;
type = Control::MenuRadioItem;
caption = strdup(_caption);
group = list;
return *this;
}
void MenuRadioItem::check() {
for(uint i = 0; i < group.count(); i++) {
CheckMenuItem(group[i].owner->info.menu_owner.group, group[i].id, MF_UNCHECKED);
}
CheckMenuItem(owner->info.menu_owner.group, id, MF_CHECKED);
}
bool MenuRadioItem::checked() {
MENUITEMINFO info;
memset(&info, 0, sizeof(info));
info.cbSize = sizeof(info);
info.fMask = MIIM_STATE;
GetMenuItemInfo(owner->info.menu_owner.group, id, false, &info);
return (info.fState & MFS_CHECKED);
}
/*****
* Container
*****/
Container& Container::create(const char *style, uint width, uint height) {
type = Control::Container;
hwnd = CreateWindow("libui_class", "", WS_CHILD | WS_VISIBLE,
0, 0, width, height, libui::message_window, (HMENU)100, GetModuleHandle(0), 0);
return *this;
}
void Container::attach(Control &control, uint x, uint y) {
owner->attach(control, x, y);
SetParent(control.hwnd, hwnd);
}
void Container::move(Control &control, uint x, uint y) {
SetWindowPos(control.hwnd, 0, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
}
/*****
* Canvas
*****/
Canvas &Canvas::create(const char *style, uint width, uint height) {
type = Control::Canvas;
char classname[4096];
sprintf(classname, "libui_class_%d", window_count++);
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 = libui_wndproc;
wc.lpszClassName = classname;
wc.lpszMenuName = 0;
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
RegisterClass(&wc);
hwnd = CreateWindow(classname, "", WS_CHILD | WS_VISIBLE,
0, 0, width, height, libui::message_window, (HMENU)100, GetModuleHandle(0), 0);
return *this;
}
WindowHandle Canvas::handle() {
return (WindowHandle)hwnd;
}
void Canvas::set_background_color(uint8 r, uint8 g, uint8 b) {
HBRUSH old_brush = background;
background = (HBRUSH)CreateSolidBrush(RGB(r, g, b));
SetClassLong(hwnd, GCL_HBRBACKGROUND, (LONG)background);
InvalidateRect(hwnd, 0, TRUE);
if(old_brush) { DeleteObject((HGDIOBJ)old_brush); }
}
/*****
* Frame
*****/
Frame& Frame::create(const char *style, uint width, uint height, const char *caption) {
type = Control::Frame;
hwnd = CreateWindow("BUTTON", caption ? caption : "", WS_CHILD | WS_VISIBLE | BS_GROUPBOX,
0, 0, width, height, libui::message_window, (HMENU)100, GetModuleHandle(0), 0);
SendMessage(hwnd, WM_SETFONT, (WPARAM)libui::font.variable, 0);
return *this;
}
/*****
* Label
*****/
Label& Label::create(const char *style, uint width, uint height, const char *caption) {
type = Control::Label;
hwnd = CreateWindow("STATIC", caption ? caption : "", WS_CHILD | WS_VISIBLE | SS_NOPREFIX | SS_ENDELLIPSIS,
0, 0, width, height, libui::message_window, (HMENU)100, GetModuleHandle(0), 0);
SendMessage(hwnd, WM_SETFONT, (WPARAM)libui::font.variable, 0);
return *this;
}
/*****
* Button
*****/
Button& Button::create(const char *style, uint width, uint height, const char *caption) {
type = Control::Button;
hwnd = CreateWindow("BUTTON", caption ? caption : "", WS_CHILD | WS_VISIBLE,
0, 0, width, height, libui::message_window, (HMENU)100, GetModuleHandle(0), 0);
SendMessage(hwnd, WM_SETFONT, (WPARAM)libui::font.variable, 0);
return *this;
}
/*****
* Checkbox
*****/
Checkbox& Checkbox::create(const char *style, uint width, uint height, const char *caption) {
type = Control::Checkbox;
hwnd = CreateWindow("BUTTON", caption ? caption : "", WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
0, 0, width, height, libui::message_window, (HMENU)100, GetModuleHandle(0), 0);
SendMessage(hwnd, WM_SETFONT, (WPARAM)libui::font.variable, 0);
return *this;
}
void Checkbox::check() {
SendMessage(hwnd, BM_SETCHECK, (WPARAM)TRUE, 0);
}
void Checkbox::uncheck() {
SendMessage(hwnd, BM_SETCHECK, (WPARAM)FALSE, 0);
}
void Checkbox::check(bool state) {
(state == true) ? check() : uncheck();
}
bool Checkbox::checked() {
return SendMessage(hwnd, BM_GETCHECK, 0, 0);
}
/*****
* Radiobox
*****/
Radiobox& Radiobox::create(ControlGroup &list, const char *style, uint width, uint height, const char *caption) {
if(list.count() == 0)throw;
type = Control::Radiobox;
group = list;
hwnd = CreateWindow("BUTTON", caption ? caption : "", WS_CHILD | WS_VISIBLE | BS_RADIOBUTTON,
0, 0, width, height, libui::message_window, (HMENU)100, GetModuleHandle(0), 0);
SendMessage(hwnd, WM_SETFONT, (WPARAM)libui::font.variable, 0);
if(this == &group[0])check();
return *this;
}
void Radiobox::check() {
for(uint i = 0; i < group.count(); i++) {
SendMessage(group[i].hwnd, BM_SETCHECK, (WPARAM)FALSE, 0);
}
SendMessage(hwnd, BM_SETCHECK, (WPARAM)TRUE, 0);
}
bool Radiobox::checked() {
return SendMessage(hwnd, BM_GETCHECK, 0, 0);
}
/*****
* Editbox
*****/
Editbox& Editbox::create(const char *style, uint width, uint height, const char *caption) {
type = Control::Editbox;
multiline = readonly = vscroll = hscroll = false;
stringarray part;
split(part, "|", style);
for(uint i = 0; i < count(part); i++) {
if(part[i] == "multiline")multiline = true;
if(part[i] == "readonly")readonly = true;
if(part[i] == "vscroll")vscroll = true;
if(part[i] == "hscroll")hscroll = true;
}
string data = caption;
replace(data, "\r", "");
replace(data, "\n", "\r\n");
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, "EDIT", strptr(data),
WS_CHILD | WS_VISIBLE |
(multiline == true ? ES_MULTILINE : 0) |
(readonly == true ? ES_READONLY : 0) |
(vscroll == true ? WS_VSCROLL : ES_AUTOVSCROLL) |
(hscroll == true ? WS_HSCROLL : ES_AUTOHSCROLL),
0, 0, width, height, libui::message_window, (HMENU)100, GetModuleHandle(0), 0);
SendMessage(hwnd, WM_SETFONT, (WPARAM)libui::font.variable, 0);
return *this;
}
/*****
* Listbox
*****/
Listbox& Listbox::create(const char *style, uint width, uint height, const char *columns, const char *data) {
stringarray part;
header = false;
split(part, "|", style);
for(uint i = 0; i < count(part); i++) {
if(part[i] == "header")header = true;
}
type = Control::Listbox;
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, WC_LISTVIEW, "",
WS_CHILD | WS_VISIBLE | LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS |
(header == true ? 0 : LVS_NOCOLUMNHEADER),
0, 0, width, height, libui::message_window, (HMENU)100, GetModuleHandle(0), 0);
SendMessage(hwnd, WM_SETFONT, (WPARAM)libui::font.variable, 0);
ListView_SetExtendedListViewStyle(hwnd, LVS_EX_FULLROWSELECT);
split(part, "|", columns);
column_count = count(part);
for(uint i = 0; i < column_count; i++) {
LVCOLUMN column;
column.mask = LVCF_FMT | LVCF_TEXT | LVCF_SUBITEM;
column.fmt = LVCFMT_LEFT;
column.iSubItem = count(part);
column.pszText = (LPSTR)strptr(part[i]);
ListView_InsertColumn(hwnd, i, &column);
}
if(strcmp(data, "")) {
split(part, "||", data);
for(uint i = 0; i < count(part); i++) {
add_item(strptr(part[i]));
}
}
autosize_columns();
return *this;
}
void Listbox::autosize_columns() {
for(uint i = 0; i < column_count; i++) {
ListView_SetColumnWidth(hwnd, i, LVSCW_AUTOSIZE_USEHEADER);
}
}
void Listbox::set_column_width(uint column, uint width) {
ListView_SetColumnWidth(hwnd, column, width);
}
void Listbox::add_item(const char *data) {
stringarray part;
split(part, "|", data);
LVITEM item;
uint pos = ListView_GetItemCount(hwnd);
item.mask = LVIF_TEXT;
item.iItem = pos;
item.iSubItem = 0;
item.pszText = (LPSTR)strptr(part[0]);
ListView_InsertItem(hwnd, &item);
for(uint i = 1; i < count(part); i++) {
ListView_SetItemText(hwnd, pos, i, (LPSTR)strptr(part[i]));
}
}
int Listbox::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 Listbox::set_selection(int index) {
uint count = ListView_GetItemCount(hwnd);
for(uint i = 0; i < count; i++) {
uint state = ListView_GetItemState(hwnd, i, LVIS_FOCUSED);
ListView_SetItemState(hwnd, i, LVIS_FOCUSED, (i == index) ? LVIS_FOCUSED : 0);
ListView_SetItemState(hwnd, i, LVIS_SELECTED, (i == index) ? LVIS_SELECTED : 0);
}
}
void Listbox::reset() {
ListView_DeleteAllItems(hwnd);
}
/*****
* Combobox
*****/
Combobox& Combobox::create(const char *style, uint width, uint height, const char *caption) {
type = Control::Combobox;
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE, "COMBOBOX", caption ? caption : "",
WS_CHILD | WS_VISIBLE | CBS_DROPDOWNLIST | CBS_HASSTRINGS,
0, 0, width, 200, libui::message_window, (HMENU)100, GetModuleHandle(0), 0);
SendMessage(hwnd, WM_SETFONT, (WPARAM)libui::font.variable, 0);
if(strcmp(caption, "")) {
stringarray temp;
split(temp, "|", caption);
for(uint i = 0; i < count(temp); i++) { add_item(strptr(temp[i])); }
set_selection(0);
}
return *this;
}
void Combobox::add_item(const char *data) {
SendMessage(hwnd, CB_ADDSTRING, 0, (LPARAM)data);
}
void Combobox::set_selection(int index) {
SendMessage(hwnd, CB_SETCURSEL, index, 0);
}
int Combobox::get_selection() {
return SendMessage(hwnd, CB_GETCURSEL, 0, 0);
}
void Combobox::reset() {
SendMessage(hwnd, CB_RESETCONTENT, 0, 0);
}
/*****
* Progressbar
*****/
Progressbar& Progressbar::create(const char *style, uint width, uint height) {
type = Control::Progressbar;
hwnd = CreateWindow(PROGRESS_CLASS, "", WS_CHILD | WS_VISIBLE | PBS_SMOOTH,
0, 0, width, height, libui::message_window, (HMENU)100, GetModuleHandle(0), 0);
SendMessage(hwnd, PBM_SETRANGE, 0, MAKELPARAM(0, 100));
SendMessage(hwnd, PBM_SETSTEP, MAKEWPARAM(1, 0), 0);
return *this;
}
void Progressbar::set_progress(uint progress) {
progress = minmax<0, 100>(progress);
SendMessage(hwnd, PBM_SETPOS, (WPARAM)progress, 0);
}
uint Progressbar::get_progress() {
return minmax<0, 100>(SendMessage(hwnd, PBM_GETPOS, 0, 0));
}
/*****
* Slider
*****/
Slider& Slider::create(const char *style, uint width, uint height, uint min, uint max) {
type = Control::Slider;
orientation = 0;
stringarray part;
split(part, "|", style);
for(uint i = 0; i < count(part); i++) {
if(part[i] == "horizontal")orientation = 0;
if(part[i] == "vertical")orientation = 1;
}
hwnd = CreateWindow(TRACKBAR_CLASS, "",
WS_CHILD | WS_VISIBLE | TBS_NOTICKS | TBS_BOTH | (orientation == 0 ? TBS_HORZ : TBS_VERT),
0, 0, width, height, libui::message_window, (HMENU)100, GetModuleHandle(0), 0);
SendMessage(hwnd, TBM_SETRANGE, (WPARAM)true, (LPARAM)MAKELONG(min, max));
SendMessage(hwnd, TBM_SETPAGESIZE, 0, (LPARAM)((max - min) >> 3));
SendMessage(hwnd, TBM_SETPOS, (WPARAM)true, (LPARAM)min);
return *this;
}
void Slider::set_position(uint position) {
SendMessage(hwnd, TBM_SETPOS, (WPARAM)true, (LPARAM)position);
}
uint Slider::get_position() {
return SendMessage(hwnd, TBM_GETPOS, 0, 0);
}
};

151
src/lib/libui_win_control.h Normal file
View File

@ -0,0 +1,151 @@
class Control { public:
Window *owner;
HWND hwnd;
uint id;
uint type;
enum {
Invalid,
MenuGroup,
MenuItem,
MenuCheckItem,
MenuRadioItem,
Container,
Canvas,
Frame,
Label,
Button,
Checkbox,
Radiobox,
Editbox,
Listbox,
Combobox,
Progressbar,
Slider,
};
void resize(uint width, uint height);
void show();
void hide();
void show(bool state);
bool visible();
void enable();
void disable();
void enable(bool state);
bool enabled();
Control() : owner(0), hwnd(0), id(0), type(Invalid) {}
};
class ControlGroup { public:
array<Control*> list;
uint count() { return list.size(); }
void add(Control &control) { list[list.size()] = &control; }
void reset() { list.reset(); }
ControlGroup &operator=(ControlGroup &source) { list = source.list; return *this; }
Control &operator[](int index) { return *list[index]; }
};
class MenuGroup : public Control { public:
bool master;
HMENU group;
char *caption;
MenuGroup &create(const char *caption);
MenuGroup() : master(false) {}
~MenuGroup() { safe_free(caption); }
};
class MenuItem : public Control { public:
char *caption;
MenuItem &create(const char *caption);
~MenuItem() { safe_free(caption); }
};
class MenuCheckItem : public Control { public:
char *caption;
MenuCheckItem &create(const char *caption);
void check();
void uncheck();
void check(bool state);
bool checked();
~MenuCheckItem() { safe_free(caption); }
};
class MenuRadioItem : public Control { public:
ControlGroup group;
char *caption;
MenuRadioItem &create(ControlGroup &list, const char *caption);
void check();
bool checked();
~MenuRadioItem() { safe_free(caption); }
};
class Container : public Control { public:
Container &create(const char *style, uint width, uint height);
void attach(Control &control, uint x, uint y);
void move(Control &control, uint x, uint y);
};
class Canvas : public Control { public:
HBRUSH background;
Canvas &create(const char *style, uint width, uint height);
WindowHandle handle();
void set_background_color(uint8 r, uint8 g, uint8 b);
Canvas() : background(0) {}
};
class Frame : public Control { public:
Frame &create(const char *style, uint width, uint height, const char *caption = "");
};
class Label : public Control { public:
Label &create(const char *style, uint width, uint height, const char *caption = "");
};
class Button : public Control { public:
Button &create(const char *style, uint width, uint height, const char *caption = "");
};
class Checkbox : public Control { public:
Checkbox &create(const char *style, uint width, uint height, const char *caption = "");
void check();
void uncheck();
void check(bool state);
bool checked();
};
class Radiobox : public Control { public:
ControlGroup group;
Radiobox &create(ControlGroup &list, const char *style, uint width, uint height, const char *caption = "");
void check();
bool checked();
};
class Editbox : public Control { public:
bool multiline;
bool readonly;
bool vscroll;
bool hscroll;
Editbox &create(const char *style, uint width, uint height, const char *caption = "");
};
class Listbox : public Control { public:
bool header;
uint column_count;
Listbox &create(const char *style, uint width, uint height, const char *columns = "", const char *data = "");
void autosize_columns();
void set_column_width(uint column, uint width);
void add_item(const char *data);
int get_selection();
void set_selection(int index);
void reset();
};
class Combobox : public Control { public:
Combobox &create(const char *style, uint width, uint height, const char *caption = "");
void add_item(const char *data);
void set_selection(int index);
int get_selection();
void reset();
};
class Progressbar : public Control { public:
Progressbar &create(const char *style, uint width, uint height);
void set_progress(uint progress);
uint get_progress();
};
class Slider : public Control { public:
bool orientation;
Slider &create(const char *style, uint width, uint height, uint min, uint max);
void set_position(uint position);
uint get_position();
};

View File

@ -0,0 +1,179 @@
namespace libui {
long __stdcall libui_wndproc(HWND hwnd, uint msg, WPARAM wparam, LPARAM lparam) {
Window *window = reinterpret_cast<Window*>(GetWindowLongPtr(hwnd, GWLP_USERDATA));
if(window) { return window->wndproc(hwnd, msg, wparam, lparam); }
return DefWindowProc(hwnd, msg, wparam, lparam);
}
long Window::wndproc(HWND hwnd, uint msg, WPARAM wparam, LPARAM lparam) {
switch(msg) {
case WM_CLOSE: {
if(close() == false) { return TRUE; }
} break;
case WM_KEYDOWN: {
keydown((int)wparam);
} break;
case WM_KEYUP: {
keyup((int)wparam);
} break;
case WM_COMMAND: {
uint i = LOWORD(wparam);
if(!info.control[i])break;
Control &control = *info.control[i];
if(control.id != i)break; //this should never happen
switch(control.type) {
case Control::MenuCheckItem: { //need to simulate auto check event
MenuCheckItem &item = static_cast<MenuCheckItem&>(control);
item.check(!item.checked()); //toggle checked status
} break;
case Control::MenuRadioItem: { //need to simulate auto radio check event
static_cast<MenuRadioItem&>(control).check();
} break;
case Control::Radiobox: {
static_cast<Radiobox&>(control).check();
} break;
}
clicked(&control);
} break;
}
return DefWindowProc(hwnd, msg, wparam, lparam);
}
WindowHandle Window::handle() {
return (WindowHandle)info.hwnd;
}
void Window::attach(Control &control, uint x, uint y, bool attach_to_window) {
info.control[info.control_index] = &control;
control.id = info.control_index++;
control.owner = this;
SetWindowLong(control.hwnd, GWL_ID, control.id);
SetWindowPos(control.hwnd, 0, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
if(attach_to_window == true) { SetParent(control.hwnd, info.hwnd); }
if(control.type == Control::Container) {
SetWindowLongPtr(control.hwnd, GWLP_USERDATA, (LONG_PTR)GetWindowLongPtr(info.hwnd, GWLP_USERDATA));
}
}
void Window::focus() {
show();
SetFocus(info.hwnd);
}
void Window::move(Control &control, uint x, uint y) {
SetWindowPos(control.hwnd, 0, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
}
void Window::create(const char *style, uint width, uint height, const char *caption) {
stringarray part;
split(part, "|", style);
for(int i = 0; i < count(part); i++) {
if(part[i] == "center") { info.center = true; }
if(part[i] == "menu") { info.has_menu = true; }
}
char classname[4096];
sprintf(classname, "libui_class_%d", window_count++);
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 = libui_wndproc;
wc.lpszClassName = classname;
wc.lpszMenuName = 0;
wc.style = CS_HREDRAW | CS_VREDRAW;
RegisterClass(&wc);
RECT rc;
SystemParametersInfo(SPI_GETWORKAREA, 0, &rc, 0);
info.hwnd = CreateWindowEx(0, classname, caption ? caption : "",
WS_POPUP | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX,
rc.left, rc.top, width, height, 0, 0, GetModuleHandle(0), 0);
info.hwnd_resize = CreateWindowEx(0, "libui_class", "",
WS_POPUP | WS_SYSMENU | WS_CAPTION | WS_MINIMIZEBOX, rc.left, rc.top, width, height, 0, 0, GetModuleHandle(0), 0);
SetWindowLongPtr(info.hwnd, GWLP_USERDATA, (LONG_PTR)this);
if(info.has_menu == true) {
info.control[info.control_index] = &info.menu_owner;
info.menu_owner.id = info.control_index++;
info.menu_owner.owner = this;
info.menu_owner.type = Control::MenuGroup;
info.menu_owner.master = true;
info.menu_owner.group = CreateMenu();
info.menu_group[++info.menu_group_index] = &info.menu_owner;
}
resize(width, height);
}
void Window::move(uint x, uint y) {
RECT rc;
SystemParametersInfo(SPI_GETWORKAREA, 0, &rc, 0);
if(x < rc.left)x = rc.left;
if(y < rc.top )y = rc.top;
SetWindowPos(info.hwnd, 0, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
}
void Window::resize(uint width, uint height) {
info.width = width;
info.height = height;
SetWindowPos(info.hwnd_resize, 0, 0, 0, width, height, SWP_NOZORDER | SWP_NOMOVE);
RECT rc;
GetClientRect(info.hwnd_resize, &rc);
width += width - (rc.right - rc.left);
height += height - (rc.bottom - rc.top);
uint x = (GetSystemMetrics(SM_CXSCREEN) - width) >> 1;
uint y = (GetSystemMetrics(SM_CYSCREEN) - height) >> 1;
SetWindowPos(info.hwnd, 0, x, y, width, height, SWP_NOZORDER | (info.center == true ? 0 : SWP_NOMOVE));
}
void Window::show() {
ShowWindow(info.hwnd, SW_NORMAL);
}
void Window::hide() {
ShowWindow(info.hwnd, SW_HIDE);
}
//
void Window::set_background_color(uint8 r, uint8 g, uint8 b) {
HBRUSH old_brush = info.background;
info.background = (HBRUSH)CreateSolidBrush(RGB(r, g, b));
SetClassLong(info.hwnd, GCL_HBRBACKGROUND, (LONG)info.background);
InvalidateRect(info.hwnd, 0, TRUE);
if(old_brush) { DeleteObject((HGDIOBJ)old_brush); }
}
//
Window::Window() {
info.background = 0;
info.center = false;
info.control_index = 1;
info.has_menu = false;
info.menu_group_index = 1;
}
};

View File

@ -1,430 +0,0 @@
/*
libups : version 0.01 ~byuu, Nach (09/30/06)
*/
#ifndef __LIBUPS
#define __LIBUPS
template<typename FT>
class UPSPatch {
public:
enum {
FLAG_INFO = 0x00000001,
};
uint32 sig;
uint16 version;
uint32 format;
uint32 flags;
uint64 original_filesize;
uint64 modified_filesize;
uint8 info_author[64 + 8];
uint8 info_version[16 + 8];
uint8 info_title[128 + 8];
uint8 info_genre[32 + 8];
uint8 info_language[32 + 8];
uint8 info_date[8 + 8];
uint8 info_website[256 + 8];
uint8 info_description[1024 + 8];
FT fp;
uint32 xmlsize;
uint32 original_crc32;
uint32 modified_crc32;
uint32 patch_crc32;
bool load();
void save_header();
void save_footer();
void close();
UPSPatch();
};
template<typename FTO, typename FTM, typename FTP>
class UPS {
public:
FTO original;
FTM modified;
UPSPatch<FTP> patch;
uint64 original_filesize;
uint64 modified_filesize;
uint64 largest_filesize;
uint32 original_crc32;
uint32 modified_crc32;
uint32 patch_crc32;
bool patch_eof;
uint ptr_read();
void ptr_write(uint ptr);
void create(const char *original_filename,
const char *modified_filename,
const char *patch_filename);
void create_linear();
bool apply(const char *original_filename,
const char *modified_filename,
const char *patch_filename);
bool apply();
void apply_linear();
};
/*****
* UPSPatch
*****/
template<typename FT>
bool UPSPatch<FT>::load() {
fseek(fp, 0, file::seek_start);
patch_crc32 = 0xffffffff;
while(ftell(fp) < fsize(fp) - 4) {
patch_crc32 = crc32_adjust(patch_crc32, fgetc(fp));
}
patch_crc32 = ~patch_crc32;
fseek(fp, -16, file::seek_end);
xmlsize = fgetld(fp);
original_crc32 = fgetld(fp);
modified_crc32 = fgetld(fp);
if(patch_crc32 != fgetld(fp)) {
fprintf(stdout, "error: patch checksum failure\n");
return false;
}
fseek(fp, 0, file::seek_start);
sig = fgetld(fp);
version = fgetlw(fp);
format = fgetld(fp);
flags = fgetld(fp);
original_filesize = fgetlq(fp);
modified_filesize = fgetlq(fp);
memset(info_author, 0, 64 + 8);
memset(info_version, 0, 16 + 8);
memset(info_title, 0, 128 + 8);
memset(info_genre, 0, 32 + 8);
memset(info_language, 0, 32 + 8);
memset(info_date, 0, 8 + 8);
memset(info_website, 0, 256 + 8);
memset(info_description, 0, 1024 + 8);
if(flags & FLAG_INFO) {
fread(fp, info_author, 64);
fread(fp, info_version, 16);
fread(fp, info_title, 128);
fread(fp, info_genre, 32);
fread(fp, info_language, 32);
fread(fp, info_date, 8);
fread(fp, info_website, 256);
fread(fp, info_description, 1024);
}
return true;
}
template<typename FT>
void UPSPatch<FT>::save_header() {
fputld(fp, sig);
fputlw(fp, version);
fputld(fp, format);
fputld(fp, flags);
fputlq(fp, original_filesize);
fputlq(fp, modified_filesize);
if(flags & FLAG_INFO) {
fwrite(fp, info_author, 64);
fwrite(fp, info_version, 16);
fwrite(fp, info_title, 128);
fwrite(fp, info_genre, 32);
fwrite(fp, info_language, 32);
fwrite(fp, info_date, 8);
fwrite(fp, info_website, 256);
fwrite(fp, info_description, 1024);
}
}
template<typename FT>
void UPSPatch<FT>::save_footer() {
fputld(fp, xmlsize);
fputld(fp, original_crc32);
fputld(fp, modified_crc32);
patch_crc32 = fcrc32(fp);
fputld(fp, patch_crc32);
}
template<typename FT>
void UPSPatch<FT>::close() {
fclose(fp);
}
template<typename FT>
UPSPatch<FT>::UPSPatch() {
sig = 0x00737075; //'ups\0'
version = 0x0001; //1.0
format = 0x00000000; //linear
flags = 0;
original_filesize = 0;
modified_filesize = 0;
memset(info_author, 0, 64 + 8);
memset(info_version, 0, 16 + 8);
memset(info_title, 0, 128 + 8);
memset(info_genre, 0, 32 + 8);
memset(info_language, 0, 32 + 8);
memset(info_date, 0, 8 + 8);
memset(info_website, 0, 256 + 8);
memset(info_description, 0, 1024 + 8);
xmlsize = 0;
original_crc32 = 0;
modified_crc32 = 0;
patch_crc32 = 0;
}
/*****
* UPS
*****/
template<typename FTO, typename FTM, typename FTP>
uint UPS<FTO, FTM, FTP>::ptr_read() {
uint len = fgetc(patch.fp);
if(len == 0xff) {
patch_eof = true;
return 0;
}
if(len <= 0xf7) {
return len;
}
len -= 0xf8;
uint ptr = 0;
for(int i = 0; i < (len + 2); i++) {
ptr |= fgetc(patch.fp) << (i << 3);
}
ptr += 0xf8;
if(len >= 1) { ptr += 0x10000; }
if(len >= 2) { ptr += 0x1000000; }
return ptr;
}
template<typename FTO, typename FTM, typename FTP>
void UPS<FTO, FTM, FTP>::ptr_write(uint ptr) {
if(ptr <= 0xf7) {
fputb(patch.fp, ptr);
return;
}
ptr -= 0xf8;
if(ptr <= 0xffff) {
fputb(patch.fp, 0xf8);
fputb(patch.fp, ptr);
fputb(patch.fp, ptr >> 8);
return;
}
ptr -= 0x10000;
if(ptr <= 0xffffff) {
fputb(patch.fp, 0xf9);
fputb(patch.fp, ptr);
fputb(patch.fp, ptr >> 8);
fputb(patch.fp, ptr >> 16);
return;
}
ptr -= 0x1000000;
fputb(patch.fp, 0xfa);
fputb(patch.fp, ptr);
fputb(patch.fp, ptr >> 8);
fputb(patch.fp, ptr >> 16);
fputb(patch.fp, ptr >> 24);
}
template<typename FTO, typename FTM, typename FTP>
void UPS<FTO, FTM, FTP>::create(
const char *original_filename,
const char *modified_filename,
const char *patch_filename
) {
fopen(original, original_filename, file::mode_read);
fopen(modified, modified_filename, file::mode_read);
fopen(patch.fp, patch_filename, file::mode_writeread);
patch.original_filesize = original_filesize = fsize(original);
patch.modified_filesize = modified_filesize = fsize(modified);
largest_filesize = (original_filesize >= modified_filesize) ?
original_filesize : modified_filesize;
patch.save_header();
switch(patch.format) {
case 0x00000000: create_linear(); break;
}
patch.original_crc32 = original_crc32 = fcrc32(original);
patch.modified_crc32 = modified_crc32 = fcrc32(modified);
patch.save_footer();
patch.close();
}
template<typename FTO, typename FTM, typename FTP>
void UPS<FTO, FTM, FTP>::create_linear() {
fseek(original, 0, file::seek_start);
fseek(modified, 0, file::seek_start);
uint last_ptr = 0, rle_count, last_out, rep_count;
for(int i = 0; i < largest_filesize;) {
uint8 r = fgetc(original) ^ fgetc(modified);
i++;
if(r == 0x00)continue;
//ptr
ptr_write((i - 1) - last_ptr);
//data
fputb(patch.fp, r);
last_out = r;
rep_count = 0;
do {
r = fgetc(original) ^ fgetc(modified);
i++;
fputb(patch.fp, r);
if(last_out != r) {
rep_count = 0;
} else {
if(++rep_count == (3 - 1)) {
rle_count = 0;
do {
r = fgetc(original) ^ fgetc(modified);
if(r != last_out || r == 0x00) { break; }
rle_count++;
} while(i < largest_filesize);
ptr_write(rle_count);
if(i < largest_filesize) { fputb(patch.fp, r); }
rep_count = 0;
}
}
last_out = r;
if(r == 0x00) { break; }
} while(i < largest_filesize);
last_ptr = i;
}
fputb(patch.fp, 0xff);
}
template<typename FTO, typename FTM, typename FTP>
bool UPS<FTO, FTM, FTP>::apply(
const char *original_filename,
const char *modified_filename,
const char *patch_filename
) {
fopen(original, original_filename, file::mode_read);
fopen(modified, modified_filename, file::mode_writeread);
fopen(patch.fp, patch_filename, file::mode_read);
return apply();
}
template<typename FTO, typename FTM, typename FTP>
bool UPS<FTO, FTM, FTP>::apply() {
patch.load();
patch_eof = false;
original_filesize = fsize(original);
original_crc32 = fcrc32(original);
if(original_filesize == patch.original_filesize &&
original_crc32 == patch.original_crc32) {
modified_filesize = patch.modified_filesize;
modified_crc32 = patch.modified_crc32;
} else if(original_filesize == patch.modified_filesize &&
original_crc32 == patch.modified_crc32) {
modified_filesize = patch.original_filesize;
modified_crc32 = patch.original_crc32;
} else {
fprintf(stdout, "error: input checksum failure\n");
return false;
}
patch_crc32 = patch.patch_crc32;
apply_linear();
patch.close();
if(modified_crc32 != fcrc32(modified)) {
fprintf(stdout, "error: output checksum failure\n");
}
return true;
}
template<typename FTO, typename FTM, typename FTP>
void UPS<FTO, FTM, FTP>::apply_linear() {
fseek(original, 0, file::seek_start);
fseek(modified, 0, file::seek_start);
for(uint i = 0; i < modified_filesize; i++) {
fputb(modified, fgetc(original));
}
fseek(original, 0, file::seek_start);
fseek(modified, 0, file::seek_start);
uint rle_count, last_in, rep_count;
while(!feof(patch.fp) && patch_eof == false && ftell(modified) < modified_filesize) {
//ptr
uint ptr = ptr_read();
if(patch_eof == true) { break; }
//data
fseek(original, ftell(original) + ptr, file::seek_start);
fseek(modified, ftell(modified) + ptr, file::seek_start);
last_in = 0;
rep_count = 0;
do {
if(ftell(modified) >= modified_filesize) { break; }
uint8 r = fgetc(patch.fp);
fputb(modified, r ^ fgetc(original));
if(r != last_in) {
rep_count = 0;
} else {
if(++rep_count == (3 - 1)) {
rle_count = ptr_read();
while(rle_count-- && ftell(modified) < modified_filesize) {
fputb(modified, r ^ fgetc(original));
}
rep_count = 0;
}
}
last_in = r;
if(r == 0x00) { break; }
} while(!feof(patch.fp) && patch_eof == false && ftell(modified) < modified_filesize);
}
}
#endif

View File

@ -1,5 +1,5 @@
/* /*
libvector : version 0.04 ~byuu (10/14/06) libvector : version 0.05 ~byuu (2006-12-16)
*/ */
/***** /*****
@ -98,7 +98,7 @@ public:
objectsize = size; objectsize = size;
} }
pool = static_cast<T*>(realloc(pool, sizeof(T) * size)); pool = (T*)realloc(pool, sizeof(T) * size);
poolsize = size; poolsize = size;
} }
@ -165,7 +165,7 @@ public:
objectsize = size; objectsize = size;
} }
pool = static_cast<T**>(realloc(pool, sizeof(T*) * size)); pool = (T**)realloc(pool, sizeof(T*) * size);
if(size > poolsize) { if(size > poolsize) {
memset(pool + poolsize, 0, sizeof(T*) * (size - poolsize)); memset(pool + poolsize, 0, sizeof(T*) * (size - poolsize));
} }

View File

@ -1,3 +1,5 @@
#include "filereader.h"
uint32 FileReader::size() { uint32 FileReader::size() {
return fsize; return fsize;
} }

View File

@ -1,3 +1,5 @@
#include "gzreader.h"
uint32 GZReader::size() { uint32 GZReader::size() {
return fsize; return fsize;
} }

View File

@ -1,11 +1,10 @@
/* /*
Copyright (C) 2005 NSRT Team ( http://nsrt.edgeemu.com ) Copyright (C) 2005-2007 NSRT Team ( http://nsrt.edgeemu.com )
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net ) Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License version 2.1 as published by the Free Software Foundation.
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -1,11 +1,10 @@
/* /*
Copyright (C) 2005 NSRT Team ( http://nsrt.edgeemu.com ) Copyright (C) 2005-2007 NSRT Team ( http://nsrt.edgeemu.com )
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net ) Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License version 2.1 as published by the Free Software Foundation.
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -4,8 +4,7 @@ Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License version 2.1 as published by the Free Software Foundation.
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -4,8 +4,7 @@ Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License version 2.1 as published by the Free Software Foundation.
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -1,11 +1,9 @@
/* /*
Copyright (C) 2004 NSRT Team ( http://nsrt.edgeemu.com ) Copyright (C) 2004-2007 NSRT Team ( http://nsrt.edgeemu.com )
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation.
version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -23,7 +21,6 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
namespace CRC32lib namespace CRC32lib
{ {
unsigned int CRC32(const unsigned char *, size_t, register unsigned int crc32 = 0xFFFFFFFF); unsigned int CRC32(const unsigned char *, size_t, register unsigned int crc32 = 0xFFFFFFFF);
unsigned short SUM_CRC32(const unsigned char *, size_t, unsigned int &crc32);
} }
#endif #endif

View File

@ -1,12 +1,11 @@
/* /*
Copyright (C) 2005 NSRT Team ( http://nsrt.edgeemu.com ) Copyright (C) 2005-2007 NSRT Team ( http://nsrt.edgeemu.com )
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net ) Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org ) Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License version 2.1 as published by the Free Software Foundation.
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -1,12 +1,11 @@
/* /*
Copyright (C) 2005 NSRT Team ( http://nsrt.edgeemu.com ) Copyright (C) 2005-2007 NSRT Team ( http://nsrt.edgeemu.com )
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net ) Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org ) Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License version 2.1 as published by the Free Software Foundation.
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -1,12 +1,11 @@
/* /*
Copyright (C) 2005 NSRT Team ( http://nsrt.edgeemu.com ) Copyright (C) 2005-2007 NSRT Team ( http://nsrt.edgeemu.com )
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net ) Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org ) Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License version 2.1 as published by the Free Software Foundation.
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -4,8 +4,7 @@ Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License version 2.1 as published by the Free Software Foundation.
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -1,11 +1,9 @@
/* /*
Copyright (C) 2004 NSRT Team ( http://nsrt.edgeemu.com ) Copyright (C) 2004-2007 NSRT Team ( http://nsrt.edgeemu.com )
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation.
version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -1,11 +1,9 @@
/* /*
Copyright (C) 2005 NSRT Team ( http://nsrt.edgeemu.com ) Copyright (C) 2005-2007 NSRT Team ( http://nsrt.edgeemu.com )
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation.
version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -1,11 +1,9 @@
/* /*
Copyright (C) 2005 NSRT Team ( http://nsrt.edgeemu.com ) Copyright (C) 2005-2007 NSRT Team ( http://nsrt.edgeemu.com )
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation.
version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -1,12 +1,11 @@
/* /*
Copyright (C) 2005 NSRT Team ( http://nsrt.edgeemu.com ) Copyright (C) 2005-2007 NSRT Team ( http://nsrt.edgeemu.com )
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net ) Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org ) Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License version 2.1 as published by the Free Software Foundation.
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -4,8 +4,7 @@ Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License version 2.1 as published by the Free Software Foundation.
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -4,8 +4,7 @@ Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License version 2.1 as published by the Free Software Foundation.
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -1,12 +1,11 @@
/* /*
Copyright (C) 2005 NSRT Team ( http://nsrt.edgeemu.com ) Copyright (C) 2005-2007 NSRT Team ( http://nsrt.edgeemu.com )
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net ) Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org ) Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License version 2.1 as published by the Free Software Foundation.
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -1,12 +1,11 @@
/* /*
Copyright (C) 2005 NSRT Team ( http://nsrt.edgeemu.com ) Copyright (C) 2005-2007 NSRT Team ( http://nsrt.edgeemu.com )
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net ) Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org ) Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License version 2.1 as published by the Free Software Foundation.
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -4,8 +4,7 @@ Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License version 2.1 as published by the Free Software Foundation.
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -1,12 +1,10 @@
/* /*
Copyright (C) 2004 NSRT Team ( http://nsrt.edgeemu.com ) Copyright (C) 2004-2007 NSRT Team ( http://nsrt.edgeemu.com )
Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net ) Copyright (C) 2002 Andrea Mazzoleni ( http://advancemame.sf.net )
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2 as published by the Free Software Foundation.
version 2 of the License, or (at your option) any later
version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -4,8 +4,7 @@ Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License version 2.1 as published by the Free Software Foundation.
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -4,8 +4,7 @@ Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License version 2.1 as published by the Free Software Foundation.
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -4,8 +4,7 @@ Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License version 2.1 as published by the Free Software Foundation.
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -4,8 +4,7 @@ Copyright (C) 2001-4 Igor Pavlov ( http://www.7-zip.org )
This library is free software; you can redistribute it and/or This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either License version 2.1 as published by the Free Software Foundation.
version 2.1 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of

View File

@ -1,6 +1,7 @@
//created by Nach //created by Nach
//#include "jma/jma.h" #include "jmareader.h"
#include "jma/jma.h"
uint32 JMAReader::size() { uint32 JMAReader::size() {
return fsize; return fsize;

View File

@ -1,10 +1,11 @@
#include "../base.h" #include "../base.h"
#include "filereader.cpp" #include "filereader.cpp"
#ifdef GZIP_SUPPORT #if defined(GZIP_SUPPORT)
#include "gzreader.cpp" #include "gzreader.cpp"
#include "zipreader.cpp" #include "zipreader.cpp"
#endif #endif
#ifdef JMA_SUPPORT #if defined(JMA_SUPPORT)
#include "jmareader.cpp" #include "jmareader.cpp"
#endif #endif

View File

@ -25,12 +25,3 @@ public:
virtual void write(uint8 *buffer, uint32 length) = 0; virtual void write(uint8 *buffer, uint32 length) = 0;
virtual bool ready() { return true; } virtual bool ready() { return true; }
}; };
#include "filereader.h"
#ifdef GZIP_SUPPORT
#include "gzreader.h"
#include "zipreader.h"
#endif
#ifdef JMA_SUPPORT
#include "jmareader.h"
#endif

View File

@ -1,5 +1,7 @@
//created by Nach //created by Nach
#include "zipreader.h"
uint32 ZipReader::size() { uint32 ZipReader::size() {
return fsize; return fsize;
} }

View File

@ -1,3 +1,4 @@
//Overload's gamma curve adjustment table
const uint8 SNES::gamma_ramp_table[32] = { const uint8 SNES::gamma_ramp_table[32] = {
0x00, 0x01, 0x03, 0x06, 0x0a, 0x0f, 0x15, 0x1c, 0x00, 0x01, 0x03, 0x06, 0x0a, 0x0f, 0x15, 0x1c,
0x24, 0x2d, 0x37, 0x42, 0x4e, 0x5b, 0x69, 0x78, 0x24, 0x2d, 0x37, 0x42, 0x4e, 0x5b, 0x69, 0x78,
@ -7,21 +8,21 @@ const uint8 SNES::gamma_ramp_table[32] = {
void SNES::contrast_adjust(int32 &input) { void SNES::contrast_adjust(int32 &input) {
double lmin, lmax; double lmin, lmax;
lmin = 0.0 - double(int32(config::snes.contrast)); lmin = 0.0 - (double)((int32)config::snes.contrast);
lmax = 255.0 + double(int32(config::snes.contrast)); lmax = 255.0 + (double)((int32)config::snes.contrast);
int32 result = int32(lmin + double(input) * ((lmax - lmin) / 256.0)); int32 result = (int32)(lmin + (double)input * ((lmax - lmin) / 256.0));
input = minmax<0, 255>(result); input = minmax<0, 255>(result);
} }
void SNES::brightness_adjust(int32 &input) { void SNES::brightness_adjust(int32 &input) {
int32 result; int32 result;
result = input + int32(config::snes.brightness); result = input + (int32)config::snes.brightness;
input = minmax<0, 255>(result); input = minmax<0, 255>(result);
} }
void SNES::gamma_adjust(int32 &input) { void SNES::gamma_adjust(int32 &input) {
int32 result; int32 result;
result = int32(pow((double(input + 1) / 256.0), double(config::snes.gamma) / 100.0) * 256.0); result = (int32)(pow(((double)(input + 1) / 256.0), (double)config::snes.gamma / 100.0) * 256.0);
input = minmax<0, 255>(result); input = minmax<0, 255>(result);
} }
@ -39,7 +40,7 @@ uint32 col;
g = (col >> 8) & 0xff; g = (col >> 8) & 0xff;
b = (col ) & 0xff; b = (col ) & 0xff;
if(bool(config::snes.gamma_ramp) == true) { if((bool)config::snes.gamma_ramp == true) {
r = gamma_ramp_table[r >> 3]; r = gamma_ramp_table[r >> 3];
g = gamma_ramp_table[g >> 3]; g = gamma_ramp_table[g >> 3];
b = gamma_ramp_table[b >> 3]; b = gamma_ramp_table[b >> 3];
@ -49,24 +50,24 @@ uint32 col;
contrast_adjust(g); brightness_adjust(g); gamma_adjust(g); contrast_adjust(g); brightness_adjust(g); gamma_adjust(g);
contrast_adjust(b); brightness_adjust(b); gamma_adjust(b); contrast_adjust(b); brightness_adjust(b); gamma_adjust(b);
if(bool(config::snes.sepia) == true) { if((bool)config::snes.sepia == true) {
l = int32(double(r) * kr + double(g) * kg + double(b) * kb); l = (int32)((double)r * kr + (double)g * kg + (double)b * kb);
l = (l > 255) ? 255 : (l < 0) ? 0 : l; l = (l > 255) ? 255 : (l < 0) ? 0 : l;
r = int32(double(l) * (1.0 + 0.300)); r = (int32)((double)l * (1.0 + 0.300));
g = int32(double(l) * (1.0 - 0.055)); g = (int32)((double)l * (1.0 - 0.055));
b = int32(double(l) * (1.0 - 0.225)); b = (int32)((double)l * (1.0 - 0.225));
r = minmax<0, 255>(r); r = minmax<0, 255>(r);
g = minmax<0, 255>(g); g = minmax<0, 255>(g);
b = minmax<0, 255>(b); b = minmax<0, 255>(b);
} }
if(bool(config::snes.grayscale) == true) { if((bool)config::snes.grayscale == true) {
l = int32(double(r) * kr + double(g) * kg + double(b) * kb); l = (int32)((double)r * kr + (double)g * kg + (double)b * kb);
l = minmax<0, 255>(l); l = minmax<0, 255>(l);
r = g = b = l; r = g = b = l;
} }
if(bool(config::snes.invert) == true) { if((bool)config::snes.invert == true) {
r ^= 0xff; r ^= 0xff;
g ^= 0xff; g ^= 0xff;
b ^= 0xff; b ^= 0xff;
@ -95,7 +96,7 @@ uint32 col;
color_lookup_table[i] = (r << 16) | (g << 8) | (b); color_lookup_table[i] = (r << 16) | (g << 8) | (b);
break; break;
default: default:
color_lookup_table[i] = uint(-1); color_lookup_table[i] = (uint)-1;
break; break;
} }
} }

View File

@ -1,248 +0,0 @@
# bsnes makefile
##################################
### platform-specific settings ###
##################################
ifeq ($(PLATFORM),x-gcc-gtk)
OS = unix
CC = gcc
CFLAGS = -O3 -fomit-frame-pointer -ffast-math -DPLATFORM_X -DCOMPILER_GCC -DPROCESSOR_X86 -DUI_GTK `pkg-config --cflags gtk+-2.0` `sdl-config --cflags`
AS = nasm
ASFLAGS = -f elf
LIBS = `pkg-config --libs gtk+-2.0` `sdl-config --libs`
endif
ifeq ($(PLATFORM),x-gcc-sdl)
OS = unix
CC = gcc
CFLAGS = -O3 -fomit-frame-pointer -ffast-math -DPLATFORM_X -DCOMPILER_GCC -DPROCESSOR_X86 -DUI_SDL `sdl-config --cflags`
AS = nasm
ASFLAGS = -f elf
LIBS = `sdl-config --libs`
endif
ifeq ($(PLATFORM),win-visualc)
OS = win
CC = cl
CFLAGS = /nologo /wd4996 /O2 /EHsc /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_WIN
AS = nasm
ASFLAGS = -f win32 -DWIN32
LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib
endif
ifeq ($(PLATFORM),win-visualc-pgi)
OS = win
CC = cl
CFLAGS = /nologo /wd4996 /O2 /GL /EHsc /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_WIN
AS = nasm
ASFLAGS = -f win32 -DWIN32
LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib
LINK = /link /PGD:bsnes.pgd /LTCG:PGINSTRUMENT
endif
ifeq ($(PLATFORM),win-visualc-pgo)
OS = win
CC = cl
CFLAGS = /nologo /wd4996 /O2 /GL /EHsc /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_WIN
AS = nasm
ASFLAGS = -f win32 -DWIN32
LIBS = d3d9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib
LINK = /link /PGD:bsnes.pgd /LTCG:PGOPTIMIZE
endif
ifeq ($(PLATFORM),win-visualc-sdl)
OS = win
CC = cl
CFLAGS = /nologo /wd4996 /O2 /EHsc /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86 /DUI_SDL
AS = nasm
ASFLAGS = -f win32 -DWIN32
LIBS = sdlmain.lib sdl.lib dsound.lib
endif
#####################################
### compiler / assembler switches ###
#####################################
ifeq ($(CC),gcc)
OUT = -obsnes
CXX = g++
OBJ = o
COBJFLAG = -c
endif
ifeq ($(CC),cl)
OUT = /Febsnes.exe
CXX = cl
OBJ = obj
COBJFLAG = /c
endif
ifeq ($(AS),nasm)
ASOBJFLAG = -o
endif
###################
### OS switches ###
###################
ifeq ($(OS),unix)
RM = rm -f
endif
ifeq ($(OS),win)
RM = del
LIBS += kernel32.lib user32.lib gdi32.lib winmm.lib comdlg32.lib comctl32.lib
endif
#########################
### begin compilation ###
#########################
OBJS = main.$(OBJ) \
libco.$(OBJ) libstring.$(OBJ) libconfig.$(OBJ) \
reader.$(OBJ) cart.$(OBJ) cheat.$(OBJ) \
memory.$(OBJ) bmemory.$(OBJ) \
cpu.$(OBJ) scpu.$(OBJ) \
smp.$(OBJ) ssmp.$(OBJ) \
bdsp.$(OBJ) \
ppu.$(OBJ) bppu.$(OBJ) \
snes.$(OBJ) \
srtc.$(OBJ) sdd1.$(OBJ) c4.$(OBJ) dsp1.$(OBJ) dsp2.$(OBJ) obc1.$(OBJ)
# 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) \
# jma.$(OBJ) jcrc32.$(OBJ) lzmadec.$(OBJ) 7zlzma.$(OBJ) iiostrm.$(OBJ) inbyte.$(OBJ) lzma.$(OBJ) winout.$(OBJ)
ifeq ($(OS),win)
ifeq ($(CC),cl)
OBJS += bsnes.res
endif
endif
all: $(OBJS)
$(CXX) $(OUT) $(CFLAGS) $(OBJS) $(LIBS) $(LINK)
# mt -nologo -manifest bsnes.exe.manifest -outputresource:bsnes.exe;1
clean:
$(RM) *.$(OBJ)
$(RM) *.res
$(RM) *.pgd
$(RM) *.pgc
$(RM) *.ilk
$(RM) *.pdb
$(RM) *.manifest
#########################
### platform-specific ###
#########################
main.$(OBJ): *.cpp *.h video/* audio/* input/* ../config/* win/* win/settings/* win/debugger/* sdl/*
$(CXX) $(CFLAGS) $(COBJFLAG) main.cpp
bsnes.res: bsnes.rc
rc /r /fobsnes.res bsnes.rc
#################
### libraries ###
#################
libco.$(OBJ): ../lib/*
$(AS) $(ASFLAGS) $(ASOBJFLAG) libco.$(OBJ) ../lib/libco_x86.asm
# $(CXX) $(CFLAGS) $(COBJFLAG) /Folibco.$(OBJ) ../lib/libco_win32.cpp
libstring.$(OBJ): ../lib/*.cpp ../lib/*.h
$(CXX) $(CFLAGS) $(COBJFLAG) ../lib/libstring.cpp
libconfig.$(OBJ): ../lib/*.cpp ../lib/*.h
$(CXX) $(CFLAGS) $(COBJFLAG) ../lib/libconfig.cpp
##############
### memory ###
##############
memory.$(OBJ): ../memory/memory.cpp ../memory/memory.h
$(CXX) $(CFLAGS) $(COBJFLAG) ../memory/memory.cpp
bmemory.$(OBJ): ../memory/bmemory/* ../memory/bmemory/mapper/*
$(CXX) $(CFLAGS) $(COBJFLAG) ../memory/bmemory/bmemory.cpp
###########
### cpu ###
###########
cpu.$(OBJ): ../cpu/*
$(CXX) $(CFLAGS) $(COBJFLAG) ../cpu/cpu.cpp
scpu.$(OBJ): ../cpu/scpu/* ../cpu/scpu/core/* ../cpu/scpu/dma/* ../cpu/scpu/memory/* ../cpu/scpu/mmio/* ../cpu/scpu/timing/*
$(CXX) $(CFLAGS) $(COBJFLAG) ../cpu/scpu/scpu.cpp
###########
### smp ###
###########
smp.$(OBJ): ../smp/*
$(CXX) $(CFLAGS) $(COBJFLAG) ../smp/smp.cpp
ssmp.$(OBJ): ../smp/ssmp/* ../smp/ssmp/core/* ../smp/ssmp/memory/* ../smp/ssmp/timing/*
$(CXX) $(CFLAGS) $(COBJFLAG) ../smp/ssmp/ssmp.cpp
###########
### dsp ###
###########
bdsp.$(OBJ): ../dsp/bdsp/*
$(CXX) $(CFLAGS) $(COBJFLAG) ../dsp/bdsp/bdsp.cpp
###########
### ppu ###
###########
ppu.$(OBJ): ../ppu/*.cpp ../ppu/*.h
$(CXX) $(CFLAGS) $(COBJFLAG) ../ppu/ppu.cpp
bppu.$(OBJ): ../ppu/bppu/*
$(CXX) $(CFLAGS) $(COBJFLAG) ../ppu/bppu/bppu.cpp
#################
### utilities ###
#################
reader.$(OBJ): ../reader/*.cpp ../reader/*.h
$(CXX) $(CFLAGS) $(COBJFLAG) ../reader/reader.cpp
cart.$(OBJ): ../cart/*.cpp ../cart/*.h
$(CXX) $(CFLAGS) $(COBJFLAG) ../cart/cart.cpp
cheat.$(OBJ): ../cheat/*.cpp ../cheat/*.h
$(CXX) $(CFLAGS) $(COBJFLAG) ../cheat/cheat.cpp
############
### snes ###
############
snes.$(OBJ): ../snes/* ../snes/video/* ../snes/audio/* ../snes/input/*
$(CXX) $(CFLAGS) $(COBJFLAG) ../snes/snes.cpp
#####################
### special chips ###
#####################
srtc.$(OBJ): ../chip/srtc/*
$(CXX) $(CFLAGS) $(COBJFLAG) ../chip/srtc/srtc.cpp
sdd1.$(OBJ): ../chip/sdd1/*
$(CXX) $(CFLAGS) $(COBJFLAG) ../chip/sdd1/sdd1.cpp
c4.$(OBJ): ../chip/c4/*
$(CXX) $(CFLAGS) $(COBJFLAG) ../chip/c4/c4.cpp
dsp1.$(OBJ): ../chip/dsp1/*
$(CXX) $(CFLAGS) $(COBJFLAG) ../chip/dsp1/dsp1.cpp
dsp2.$(OBJ): ../chip/dsp2/*
$(CXX) $(CFLAGS) $(COBJFLAG) ../chip/dsp2/dsp2.cpp
obc1.$(OBJ): ../chip/obc1/*
$(CXX) $(CFLAGS) $(COBJFLAG) ../chip/obc1/obc1.cpp
############
### zlib ###
############
adler32.$(OBJ): ../reader/zlib/*.c ../reader/zlib/*.h
$(CC) $(CFLAGS) $(COBJFLAG) ../reader/zlib/*.c
###########
### jma ###
###########
jma.$(OBJ): ../reader/jma/*.cpp ../reader/jma/*.h
$(CXX) $(CFLAGS) $(COBJFLAG) ../reader/jma/*.cpp

64
src/ui/audio/ao.cpp Normal file
View File

@ -0,0 +1,64 @@
uint AudioAO::object_count = 0;
void AudioAO::run(uint32 sample) {
ao_play(audio_device, (char *)&sample, 4); //This may need to be byte swapped for Big Endian
}
void AudioAO::set_frequency(uint freq) {
Audio::set_frequency(freq);
driver_format.rate = frequency;
if(audio_device) {
term();
init();
}
}
void AudioAO::init() {
audio_device = ao_open_live(driver_id, &driver_format, 0);
if(audio_device) {
ao_info *di = ao_driver_info(driver_id);
} else {
dprintf("libao: failed to open audio device.\n");
}
}
void AudioAO::term() {
if(audio_device) {
ao_close(audio_device);
audio_device = 0;
}
}
void AudioAO::set_driver(const char *name) {
driver_id = ao_driver_id(name);
if(driver_id < 0) { //If a driver by that name doesn't exist, we use the default driver for that OS
dprintf("libao: %s is not a valid audio driver ... using default driver.\n", name);
driver_id = ao_default_driver_id();
}
if(audio_device) {
term();
init();
}
}
AudioAO::AudioAO() {
if(!object_count++) {
ao_initialize();
}
driver_id = ao_default_driver_id();
driver_format.bits = 16;
driver_format.channels = 2;
driver_format.rate = frequency;
driver_format.byte_format = AO_FMT_LITTLE;
audio_device = 0;
}
AudioAO::~AudioAO() {
if(audio_device) {
ao_close(audio_device);
}
if(!--object_count) {
ao_shutdown();
}
}

21
src/ui/audio/ao.h Normal file
View File

@ -0,0 +1,21 @@
#include <ao/ao.h>
class AudioAO : public Audio {
private:
static uint object_count;
int driver_id;
ao_sample_format driver_format;
ao_device *audio_device;
public:
void run(uint32 sample);
void set_frequency(uint freq);
void init();
void term();
void set_driver(const char *name);
AudioAO();
~AudioAO();
};

19
src/ui/audio/audio.cpp Normal file
View File

@ -0,0 +1,19 @@
void Audio::resample_point(
uint32 *output, uint32 *input, uint output_samples, uint input_samples
) {
for(uint i = 0; i < output_samples; i++) {
output[i] = input[
uint32( double(input_samples) / double(output_samples) * double(i) )
];
}
}
void Audio::set_frequency(uint freq) {
frequency = freq;
latency = (double(frequency) / 1000.0) * (double(config::audio.latency) / 3.0);
}
Audio::Audio() {
frequency = config::audio.frequency;
latency = (double(frequency) / 1000.0) * (double(config::audio.latency) / 3.0);
}

View File

@ -1,11 +1,14 @@
class Audio { class Audio {
public: public:
uint frequency; uint frequency, latency;
virtual void tick() {}
virtual void run(uint32 sample) {} virtual void run(uint32 sample) {}
virtual void set_frequency(uint new_freq) {} virtual void set_frequency(uint freq);
virtual void clear_audio() {} virtual void clear_audio() {}
virtual void init() {} virtual void init() {}
virtual void term() {} virtual void term() {}
Audio() : frequency(32000) {} void resample_point(uint32 *output, uint32 *input, uint output_samples, uint input_samples);
Audio();
} *uiAudio; } *uiAudio;

View File

@ -1,45 +1,62 @@
void AudioDS::run(uint32 sample) { void AudioDS::tick() {
data.buffer[data.buffer_pos++] = sample;
if(data.buffer_pos >= data.samples_per_frame) {
uint32 pos, size;
void *buffer;
if(config::system.regulate_speed == true) {
for(;;) {
dsb_b->GetCurrentPosition(&pos, 0);
data.read_buffer = pos / data.buffer_size;
if(data.read_buffer != data.prev_buffer)break;
Sleep(1);
}
}
data.prev_buffer = data.read_buffer;
data.read_buffer++;
data.read_buffer %= data.buffer_count;
pos = (data.read_buffer + 1) % data.buffer_count;
if(dsb_b->Lock(pos * data.buffer_size,
data.buffer_size, &buffer, &size, 0, 0, 0) == DS_OK) {
memcpy(buffer, data.buffer, data.buffer_size);
dsb_b->Unlock(buffer, size, 0, 0);
}
data.buffer_pos = 0;
}
} }
void AudioDS::set_frequency(uint new_freq) { void AudioDS::run(uint32 sample) {
frequency = new_freq; data.buffer[data.buffer_pos++] = sample;
run_audiosync();
}
void AudioDS::run_videosync() {
if(data.buffer_pos & 255)return;
uint32 ring_pos, pos, size;
dsb_b->GetCurrentPosition(&pos, 0);
ring_pos = pos / data.ring_size;
if(ring_pos == data.ring_pos)return;
data.ring_pos = ring_pos;
void *output;
if(dsb_b->Lock(((data.ring_pos + 2) % 3) * data.ring_size,
data.ring_size, &output, &size, 0, 0, 0) == DS_OK) {
Audio::resample_point((uint32*)output, data.buffer, latency, data.buffer_pos);
dsb_b->Unlock(output, size, 0, 0);
}
dprintf("AudioDS: resample_point() %d -> %d samples\n", data.buffer_pos, latency);
data.buffer_pos = 0;
}
void AudioDS::run_audiosync() {
if(data.buffer_pos < latency)return;
uint32 ring_pos, pos, size;
do {
Sleep(1);
dsb_b->GetCurrentPosition(&pos, 0);
ring_pos = pos / data.ring_size;
} while(config::system.regulate_speed == true && ring_pos == data.ring_pos);
data.ring_pos = ring_pos;
void *output;
if(dsb_b->Lock(((data.ring_pos + 2) % 3) * data.ring_size,
data.ring_size, &output, &size, 0, 0, 0) == DS_OK) {
memcpy(output, data.buffer, data.ring_size);
dsb_b->Unlock(output, size, 0, 0);
}
data.buffer_pos = 0;
}
void AudioDS::set_frequency(uint freq) {
Audio::set_frequency(freq);
init(); init();
} }
void AudioDS::clear_audio() { void AudioDS::clear_audio() {
data.read_buffer = 0; data.buffer_pos = 0;
data.prev_buffer = 0; data.ring_pos = 0;
data.buffer_pos = 0;
if(data.buffer) { if(data.buffer) {
memset(data.buffer, 0, data.buffer_size * data.buffer_count); memset(data.buffer, 0, data.buffer_size);
} }
if(!dsb_b)return; if(!dsb_b)return;
@ -48,10 +65,10 @@ void AudioDS::clear_audio() {
dsb_b->SetCurrentPosition(0); dsb_b->SetCurrentPosition(0);
uint32 size; uint32 size;
void *buffer; void *output;
dsb_b->Lock(0, data.buffer_size * data.buffer_count, &buffer, &size, 0, 0, 0); dsb_b->Lock(0, data.ring_size * 3, &output, &size, 0, 0, 0);
memset(buffer, 0, data.buffer_size * data.buffer_count); memset(output, 0, size);
dsb_b->Unlock(buffer, size, 0, 0); dsb_b->Unlock(output, size, 0, 0);
dsb_b->Play(0, 0, DSBPLAY_LOOPING); dsb_b->Play(0, 0, DSBPLAY_LOOPING);
} }
@ -60,10 +77,10 @@ void AudioDS::init() {
clear_audio(); clear_audio();
term(); term();
data.samples_per_frame = (uint)( (double)frequency / ((snes.region() == SNES::NTSC) ? 60.0 : 50.0) + 0.5 ); data.ring_size = latency * sizeof(uint32);
data.buffer_size = data.samples_per_frame * sizeof(uint32); data.buffer_size = data.ring_size * 16;
data.buffer_count = 4; data.buffer = (uint32*)malloc(data.buffer_size);
data.buffer = (uint32*)malloc(data.buffer_size * data.buffer_count); data.buffer_pos = 0;
DirectSoundCreate(0, &ds, 0); DirectSoundCreate(0, &ds, 0);
ds->SetCooperativeLevel(hwnd, DSSCL_PRIORITY); ds->SetCooperativeLevel(hwnd, DSSCL_PRIORITY);
@ -88,27 +105,37 @@ void AudioDS::init() {
dsbd.dwSize = sizeof(dsbd); dsbd.dwSize = sizeof(dsbd);
dsbd.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLFREQUENCY | dsbd.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLFREQUENCY |
DSBCAPS_GLOBALFOCUS | DSBCAPS_LOCSOFTWARE; DSBCAPS_GLOBALFOCUS | DSBCAPS_LOCSOFTWARE;
dsbd.dwBufferBytes = data.buffer_size * data.buffer_count; dsbd.dwBufferBytes = data.ring_size * 3;
dsbd.guid3DAlgorithm = GUID_NULL; dsbd.guid3DAlgorithm = GUID_NULL;
dsbd.lpwfxFormat = &wfx; dsbd.lpwfxFormat = &wfx;
ds->CreateSoundBuffer(&dsbd, &dsb_b, 0); ds->CreateSoundBuffer(&dsbd, &dsb_b, 0);
dsb_b->SetFrequency(frequency); dsb_b->SetFrequency(frequency);
dsb_b->SetCurrentPosition(0); dsb_b->SetCurrentPosition(0);
uint32 size; clear_audio();
void *buffer;
dsb_b->Lock(0, data.buffer_size * data.buffer_count, &buffer, &size, 0, 0, 0);
memset(buffer, 0, data.buffer_size * data.buffer_count);
dsb_b->Unlock(buffer, size, 0, 0);
data.read_buffer = 0;
dsb_b->Play(0, 0, DSBPLAY_LOOPING);
} }
void AudioDS::term() { void AudioDS::term() {
SafeFree(data.buffer); safe_free(data.buffer);
if(dsb_b) { dsb_b->Stop(); dsb_b->Release(); dsb_b = 0; } if(dsb_b) { dsb_b->Stop(); dsb_b->Release(); dsb_b = 0; }
if(dsb_p) { dsb_p->Stop(); dsb_p->Release(); dsb_p = 0; } if(dsb_p) { dsb_p->Stop(); dsb_p->Release(); dsb_p = 0; }
if(ds) { ds->Release(); ds = 0; } if(ds) { ds->Release(); ds = 0; }
}
AudioDS::AudioDS(HWND handle) {
hwnd = handle ? handle : GetDesktopWindow();
ds = 0;
dsb_p = 0;
dsb_b = 0;
data.buffer = 0;
data.buffer_pos = 0;
data.ring_pos = 0;
data.buffer_size = 0;
data.ring_size = 0;
}
AudioDS::~AudioDS() {
term();
} }

View File

@ -10,31 +10,20 @@ WAVEFORMATEX wfx;
struct { struct {
uint32 *buffer; uint32 *buffer;
uint read_buffer, prev_buffer; uint buffer_pos, ring_pos;
uint samples_per_frame; uint buffer_size, ring_size;
uint buffer_pos, buffer_size, buffer_count;
} data; } data;
void tick();
void run(uint32 sample); void run(uint32 sample);
void set_frequency(uint new_freq); void set_frequency(uint freq);
void clear_audio(); void clear_audio();
void init(); void init();
void term(); void term();
AudioDS(HWND handle = 0) { void run_videosync();
hwnd = (handle) ? handle : GetDesktopWindow(); void run_audiosync();
ds = 0;
dsb_p = 0;
dsb_b = 0;
data.buffer = 0; AudioDS(HWND handle = 0);
data.read_buffer = 0; ~AudioDS();
data.prev_buffer = 0;
data.samples_per_frame = 0;
data.buffer_pos = 0;
data.buffer_size = 0;
data.buffer_count = 0;
}
~AudioDS() { term(); }
}; };

View File

@ -1,3 +0,0 @@
@make PLATFORM=win-visualc
@move bsnes.exe ../../bsnes.exe>nul
@pause

View File

@ -1,2 +0,0 @@
#!/bin/sh
gmake PLATFORM=x-gcc-gtk

View File

@ -1,2 +0,0 @@
#!/bin/sh
gmake PLATFORM=x-gcc-gtk clean

View File

@ -57,6 +57,18 @@ Setting Video::pscanline_intensity(&config_file, "video.pscanline_intensity",
Setting Video::iscanline_intensity(&config_file, "video.iscanline_intensity", Setting Video::iscanline_intensity(&config_file, "video.iscanline_intensity",
"Interlace scanline intensity", 50, Setting::DEC); "Interlace scanline intensity", 50, Setting::DEC);
struct Audio {
static Setting frequency;
static Setting latency;
} audio;
Setting Audio::frequency(&config_file, "audio.frequency", "Default audio playback frequency.", 32000, Setting::DEC);
Setting Audio::latency(&config_file, "audio.latency", "Audio playback latency in milliseconds.\n"
"Specifies how long audio playback is delayed compared to a real SNES.\n"
"A delay is necessary to allow smooth audio playback via buffering.\n"
"Raising this value may help with audio playback problems, but will decrease\n"
"audio responsiveness.",
75, Setting::DEC);
struct Input { struct Input {
static Setting axis_resistance; static Setting axis_resistance;
struct Joypad1 { struct Joypad1 {

View File

@ -1,48 +0,0 @@
void bSNES::set_status(uint32 new_status) { run_status = new_status; }
uint32 bSNES::get_status() { return run_status; }
void bSNES::run() {
if(cartridge.loaded() == false)return;
switch(run_status) {
case RUN:
SNES::runtoframe();
return;
case STOP:
return;
}
}
void bSNES::video_run() {
if(r_ppu->status.frames_updated == true) {
char t[256];
r_ppu->status.frames_updated = false;
sprintf(t, "%s : %d fps", BSNES_TITLE, r_ppu->status.frames_executed);
gtk_window_set_title(GTK_WINDOW(main_window.window), t);
}
uiVideo->redraw();
}
void bSNES::sound_run(uint32 data) {
uiAudio->run(data);
}
uint16 *bSNES::video_lock(uint &pitch) {
return uiVideo->lock(pitch);
}
void bSNES::video_unlock() {
uiVideo->unlock();
}
void bSNES::poll_input(uint8 type) {
uiInput->poll(type);
}
bool bSNES::get_input_status(uint8 device, uint8 button) {
return uiInput->get_status(device, button);
}
void bSNES::notify(uint32 message, uint32 param1, uint32 param2) {}
bSNES::bSNES() { run_status = STOP; }

View File

@ -1,22 +0,0 @@
class bSNES : public SNES {
private:
uint32 run_status;
public:
enum { STOP = 0, RUN };
void run();
void video_run();
void sound_run(uint32 data);
uint16 *video_lock(uint &pitch);
void video_unlock();
void set_status(uint32 status);
uint32 get_status();
void poll_input(uint8 type);
bool get_input_status(uint8 device, uint8 button);
void notify(uint32 message, uint32 param1, uint32 param2);
bSNES();
} *bsnes;

View File

@ -1,192 +0,0 @@
const char about_text[4096] = ""
"bsnes -- version " BSNES_VERSION "\r\n"
"Author: byuu\r\n"
"Project began: October 14th, 2004\r\n"
"\r\n\r\n"
"Contributors:\r\n"
" anomie, blargg, DMV27, GIGO, kode54, Nach,\r\n"
" Overload, Richard Bannister, TRAC, zones";
struct MainWindow {
GtkWidget *window;
GtkWidget *box;
GtkWidget *menu;
GtkWidget *menu_file, *menu_file_item;
GtkWidget *menu_file_loadrom;
GtkWidget *menu_file_unloadrom;
GtkWidget *menu_file_separator1;
GtkWidget *menu_file_reset;
GtkWidget *menu_file_power;
GtkWidget *menu_file_separator2;
GtkWidget *menu_file_quit;
GtkWidget *menu_help, *menu_help_item;
GtkWidget *menu_help_about;
GdkColor render_bg;
GtkWidget *render;
GtkWidget *fileopen;
GtkWidget *aboutbox;
} main_window;
void init_main_window();
void menu_main_window(const char *item);
void term_main_window();
void load_rom();
void cancel_load_rom();
void unload_rom();
void snes_reset();
void snes_power();
void close_aboutbox();
void init_main_window() {
MainWindow *w = &main_window;
//
//create window
//
w->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(w->window), BSNES_TITLE);
gtk_window_set_resizable(GTK_WINDOW(w->window), false);
g_signal_connect(G_OBJECT(w->window), "destroy", G_CALLBACK(term_main_window), 0);
//
//create widget container
//
w->box = gtk_vbox_new(false, 0);
gtk_container_add(GTK_CONTAINER(w->window), w->box);
gtk_widget_show(w->box);
//
//create menu
//
w->menu = gtk_menu_bar_new();
gtk_widget_show(w->menu);
w->menu_file = gtk_menu_new();
w->menu_file_item = gtk_menu_item_new_with_label("File");
gtk_widget_show(w->menu_file_item);
#define add_item(menu, item, label, id) \
item = gtk_menu_item_new_with_label(label); \
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); \
g_signal_connect_swapped(G_OBJECT(item), "activate", G_CALLBACK(menu_main_window), (gpointer)id); \
gtk_widget_show(item)
#define add_separator(menu, item) \
item = gtk_separator_menu_item_new(); \
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item); \
gtk_widget_show(item)
add_item (w->menu_file, w->menu_file_loadrom, "Load ROM", "file.loadrom");
add_item (w->menu_file, w->menu_file_unloadrom, "Unload ROM", "file.unloadrom");
add_separator(w->menu_file, w->menu_file_separator1);
add_item (w->menu_file, w->menu_file_reset, "Reset", "file.reset");
add_item (w->menu_file, w->menu_file_power, "Power (Hard Reset)", "file.power");
add_separator(w->menu_file, w->menu_file_separator2);
add_item (w->menu_file, w->menu_file_quit, "Quit", "file.quit");
w->menu_help = gtk_menu_new();
w->menu_help_item = gtk_menu_item_new_with_label("Help");
gtk_widget_show(w->menu_help_item);
add_item (w->menu_help, w->menu_help_about, "About", "help.about");
gtk_menu_item_set_submenu(GTK_MENU_ITEM(w->menu_file_item), w->menu_file);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(w->menu_help_item), w->menu_help);
gtk_menu_bar_append(GTK_MENU_BAR(w->menu), w->menu_file_item);
gtk_menu_bar_append(GTK_MENU_BAR(w->menu), w->menu_help_item);
#undef add_item
#undef add_separator
//
//create render widget
//
w->render_bg.pixel = 0;
w->render_bg.red = 0;
w->render_bg.green = 0;
w->render_bg.blue = 0;
w->render = gtk_drawing_area_new();
gtk_widget_set_size_request(w->render, 256, 224);
gtk_widget_modify_bg(w->render, GTK_STATE_NORMAL, &w->render_bg);
gtk_widget_show(w->render);
//
//pack widgets
//
gtk_box_pack_start(GTK_BOX(w->box), w->menu, false, false, 0);
gtk_box_pack_end(GTK_BOX(w->box), w->render, true, true, 0);
//
//display window
//
gtk_widget_show(w->window);
while(gtk_events_pending() == true) {
gtk_main_iteration_do(false);
}
//
//initializations
//
w->fileopen = 0;
}
void menu_main_window(const char *item) {
MainWindow *w = &main_window;
if(!strcmp(item, "file.loadrom")) {
if(!w->fileopen) {
w->fileopen = gtk_file_selection_new("Load ROM");
g_signal_connect_swapped(G_OBJECT(w->fileopen), "destroy", G_CALLBACK(cancel_load_rom), 0);
g_signal_connect_swapped(G_OBJECT(GTK_FILE_SELECTION(w->fileopen)->ok_button), "clicked", G_CALLBACK(load_rom), 0);
g_signal_connect_swapped(G_OBJECT(GTK_FILE_SELECTION(w->fileopen)->cancel_button), "clicked", G_CALLBACK(gtk_widget_destroy), (gpointer)w->fileopen);
}
gtk_widget_show(w->fileopen);
} else if(!strcmp(item, "file.unloadrom")) {
if(cartridge.loaded() == true) { cartridge.unload(); }
gtk_window_set_title(GTK_WINDOW(w->window), BSNES_TITLE);
gdk_window_invalidate_rect(GDK_WINDOW(w->render->window), 0, true);
} else if(!strcmp(item, "file.reset")) {
bsnes->reset();
} else if(!strcmp(item, "file.power")) {
bsnes->power();
} else if(!strcmp(item, "file.quit")) {
term_main_window();
} else if(!strcmp(item, "help.about")) {
if(!w->aboutbox) {
w->aboutbox = gtk_message_dialog_new(0, (GtkDialogFlags)0, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, about_text);
gtk_window_set_title(GTK_WINDOW(w->aboutbox), "About bsnes...");
g_signal_connect_swapped(G_OBJECT(w->aboutbox), "destroy", G_CALLBACK(close_aboutbox), 0);
g_signal_connect_swapped(G_OBJECT(w->aboutbox), "response", G_CALLBACK(gtk_widget_destroy), (gpointer)w->aboutbox);
}
gtk_widget_show(w->aboutbox);
}
}
void term_main_window() {
running = false;
}
void load_rom() {
if(!main_window.fileopen)return;
const char *fn = gtk_file_selection_get_filename(GTK_FILE_SELECTION(main_window.fileopen));
gtk_widget_hide(main_window.fileopen);
if(cartridge.loaded() == true) { cartridge.unload(); }
if(cartridge.load(fn) == false) { return; }
bsnes->power();
}
void cancel_load_rom() {
main_window.fileopen = 0;
}
void close_aboutbox() {
main_window.aboutbox = 0;
}

View File

@ -1,93 +0,0 @@
#warning "WARNING: GTK+ port input is currently broken! Controls will not work! Please use SDL port instead."
#include "main.h"
#include "bsnes.h"
#include "gtk_mainwindow.cpp"
#include "bsnes.cpp"
#include "../video/gtk.h"
#include "../video/gtk.cpp"
#include "../video/sdl.h"
#include "../video/sdl.cpp"
#ifdef PLATFORM_WIN
#include "../audio/dsound.h"
#include "../audio/dsound.cpp"
#endif
#include "../input/sdl.h"
#include "../input/sdl.cpp"
void alert(char *s, ...) {
char str[4096];
va_list args;
va_start(args, s);
vsprintf(str, s, args);
va_end(args);
#ifdef PLATFORM_WIN
MessageBox(0, str, "bsnes", MB_OK);
#else
fprintf(stdout, "%s\r\n", str);
#endif
}
void dprintf(char *s, ...) {
char str[4096];
va_list args;
va_start(args, s);
vsprintf(str, s, args);
va_end(args);
fprintf(stdout, "%s\r\n", str);
}
#ifdef PLATFORM_WIN
int __stdcall WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) {
int argc = __argc;
char **argv = __argv;
#else
int main(int argc, char *argv[]) {
#endif
gtk_init(&argc, &argv);
init_main_window();
config_file.load("bsnes.cfg");
init_snes();
uiVideo = new VideoSDL((void*)GDK_WINDOW_XWINDOW(main_window.render->window));
uiAudio = new Audio();
uiInput = new InputSDL((void*)GDK_WINDOW_XWINDOW(main_window.render->window));
uiVideo->init();
uiAudio->init();
uiInput->init();
//will not run if cartridge not loaded
bsnes->set_status(bSNES::RUN);
if(argc >= 2 && cartridge.load(argv[1]) == true) {
snes->power();
}
while(running == true) {
bsnes->run();
while(gtk_events_pending() == true) {
gtk_main_iteration_do(false);
}
SDL_Event event;
while(SDL_PollEvent(&event)) {
}
}
end:
config_file.save("bsnes.cfg");
cartridge.unload();
uiVideo->term();
uiAudio->term();
uiInput->term();
SafeDelete(uiVideo);
SafeDelete(uiAudio);
SafeDelete(uiInput);
term_snes();
return 0;
}

View File

@ -1,4 +0,0 @@
#include <gdk/gdkx.h>
#include <gtk/gtk.h>
bool running = true; //set to false to terminate main program loop

View File

@ -1,5 +1,5 @@
void InputDI::poll() { void InputDI::poll() {
if(wMain.hwnd != GetForegroundWindow()) { if(owner != GetForegroundWindow()) {
clear_input(); clear_input();
return; return;
} }
@ -66,7 +66,7 @@ HRESULT hr = di->CreateDevice(instance->guidInstance, &di_joy[di_joy_count], 0);
} }
di_joy[di_joy_count]->SetDataFormat(&c_dfDIJoystick2); di_joy[di_joy_count]->SetDataFormat(&c_dfDIJoystick2);
di_joy[di_joy_count]->SetCooperativeLevel(wMain.hwnd, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND); di_joy[di_joy_count]->SetCooperativeLevel(owner, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND);
if(++di_joy_count >= INPUT_JOYMAX) { if(++di_joy_count >= INPUT_JOYMAX) {
//too many joypads? //too many joypads?
@ -89,7 +89,7 @@ void InputDI::init() {
di->CreateDevice(GUID_SysKeyboard, &di_key, 0); di->CreateDevice(GUID_SysKeyboard, &di_key, 0);
di_key->SetDataFormat(&c_dfDIKeyboard); di_key->SetDataFormat(&c_dfDIKeyboard);
di_key->SetCooperativeLevel(wMain.hwnd, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND); di_key->SetCooperativeLevel(owner, DISCL_NONEXCLUSIVE | DISCL_BACKGROUND);
di_key->Acquire(); di_key->Acquire();
di->EnumDevices(DI8DEVCLASS_GAMECTRL, DI_EnumJoypadsCallback, 0, DIEDFL_ATTACHEDONLY); di->EnumDevices(DI8DEVCLASS_GAMECTRL, DI_EnumJoypadsCallback, 0, DIEDFL_ATTACHEDONLY);

View File

@ -3,9 +3,10 @@
class InputDI : public Input { class InputDI : public Input {
public: public:
LPDIRECTINPUT8 di; HWND owner;
LPDIRECTINPUT8 di;
LPDIRECTINPUTDEVICE8 di_key, di_joy[INPUT_JOYMAX]; LPDIRECTINPUTDEVICE8 di_key, di_joy[INPUT_JOYMAX];
uint32 di_joy_count; uint32 di_joy_count;
void poll_hw(); void poll_hw();
void poll(); void poll();
@ -14,7 +15,8 @@ uint32 di_joy_count;
bool enum_joypads(const DIDEVICEINSTANCE *instance); bool enum_joypads(const DIDEVICEINSTANCE *instance);
InputDI() { InputDI(HWND hwnd) {
owner = hwnd;
di = 0; di = 0;
di_key = 0; di_key = 0;
for(int i = 0; i < INPUT_JOYMAX; i++)di_joy[i] = 0; for(int i = 0; i < INPUT_JOYMAX; i++)di_joy[i] = 0;

View File

@ -1,5 +1,5 @@
void InputSDL::poll(uint8 device) { void InputSDL::poll(uint8 device) {
Input::poll(device); Input::poll();
} }
void InputSDL::poll() { void InputSDL::poll() {

46
src/ui/lui/event.cpp Normal file
View File

@ -0,0 +1,46 @@
namespace event {
bool load_rom(char *fn) {
stringarray dir;
strcpy(fn, "");
strcpy(dir, config::path.rom);
replace(dir, "\\", "/");
if(strlen(dir) && !strend(dir, "/")) { strcat(dir, "/"); }
//append base_path if rom_path is relative
if(strbegin(dir, "./")) {
strltrim(dir, "./");
strcpy(dir[1], dir[0]);
strcpy(dir[0], config::path.base);
strcat(dir[0], dir[1]);
}
return window_main.file_load(fn,
"SNES images;*.smc,*.sfc,*.swc,*.fig,*.ufo,*.gd3,*.078,*.st"
#if defined(GZIP_SUPPORT)
",*.gz,*.z,*.zip"
#endif
#if defined(JMA_SUPPORT)
",*.jma"
#endif
"|All files;*.*",
strptr(dir));
}
void load_rom_normal() {
char fn[4096];
if(load_rom(fn) == false)return;
if(cartridge.loaded() == true)cartridge.unload();
cartridge.load_begin(Cartridge::CART_NORMAL);
cartridge.load(fn);
cartridge.load_end();
snes.power();
}
void unload_rom() {
cartridge.unload();
uiAudio->clear_audio();
}
};

7
src/ui/lui/event.h Normal file
View File

@ -0,0 +1,7 @@
namespace event {
bool load_rom(char *fn);
void load_rom_normal();
void unload_rom();
};

72
src/ui/lui/main.cpp Normal file
View File

@ -0,0 +1,72 @@
#if defined(PLATFORM_WIN)
#include "../../lib/libui_win.cpp"
#elif defined(PLATFORM_X)
#include "../../lib/libui_gtk.cpp"
#else
#error "unsupported platform"
#endif
namespace ui = libui;
bool _term_ = false;
#include "ui.h"
#include "event.h"
#include "ui.cpp"
#include "event.cpp"
void alert(char *s, ...) {
char str[4096];
va_list args;
va_start(args, s);
vsprintf(str, s, args);
va_end(args);
fprintf(stdout, "%s\r\n", str);
}
void dprintf(char *s, ...) {
char str[4096];
va_list args;
va_start(args, s);
vsprintf(str, s, args);
va_end(args);
fprintf(stdout, "%s\r\n", str);
}
void dprintf(uint source, char *s, ...) {
char str[4096];
va_list args;
va_start(args, s);
vsprintf(str, s, args);
va_end(args);
fprintf(stdout, "[%d]: %s\r\n", source, str);
}
#if defined(PLATFORM_WIN)
int __stdcall WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) {
int argc = __argc;
char **argv = __argv;
#else
int main(int argc, char *argv[]) {
#endif
//int main(int argc, char *argv[]) {
ui::init();
config_file.load("bsnes_lui.cfg");
init_snes();
ui_init();
while(_term_ == false) {
while(ui::events_pending() == true) { ui::run(); }
if(cartridge.loaded() == true)snes.runtoframe();
}
if(cartridge.loaded() == true)cartridge.unload();
config_file.save("bsnes_lui.cfg");
term_snes();
ui_term();
ui::term();
return 0;
}

View File

@ -0,0 +1,17 @@
bool SettingsWindow::close() {
hide();
return false;
}
void SettingsWindow::setup() {
create("center", 640, 365, "bsnes Configuration Settings");
attach(panel.create("", 150, 355), 5, 5);
panel.add_item("Video Settings");
panel.add_item("Color Adjustment");
panel.add_item("Raster Settings");
panel.add_item("Emulation Settings");
panel.add_item("Input Configuration");
panel.add_item("Cheat Code Editor");
panel.autosize_columns();
}

Some files were not shown because too many files have changed in this diff Show More