* gcc flags: add -march=pentium-mmx -fno-rtti

* menuetlibc: fix printf, sprintf
* menuetlibc: alias clock() to sysfn 26.9.
  Not exactly what is required by POSIX, but better than zero
* autobuild games/checkers

git-svn-id: svn://kolibrios.org@5123 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
CleverMouse 2014-09-15 09:42:01 +00:00
parent e147a8e695
commit fbdccce9a4
46 changed files with 146 additions and 3827 deletions

View File

@ -51,7 +51,6 @@ img_files = {
{"File Managers/EOLITE.INI", "common/File Managers/eolite.ini"}, {"File Managers/EOLITE.INI", "common/File Managers/eolite.ini"},
{"File Managers/ICONS.INI", "common/File Managers/icons.ini"}, {"File Managers/ICONS.INI", "common/File Managers/icons.ini"},
{"File Managers/KFM.INI", "common/File Managers/kfm.ini"}, {"File Managers/KFM.INI", "common/File Managers/kfm.ini"},
{"GAMES/CHECKERS", build_type .. "/games/checkers"},
{"GAMES/MEGAMAZE", build_type .. "/games/megamaze"}, {"GAMES/MEGAMAZE", build_type .. "/games/megamaze"},
{"LIB/PIXLIB.OBJ", "common/lib/pixlib.obj"}, {"LIB/PIXLIB.OBJ", "common/lib/pixlib.obj"},
{"LIB/ICONV.OBJ", "common/lib/iconv.obj"}, {"LIB/ICONV.OBJ", "common/lib/iconv.obj"},
@ -456,6 +455,7 @@ if tup.getconfig('NO_GCC') ~= 'full' then
tup.append_table(img_files, { tup.append_table(img_files, {
{"3D/CUBELINE", PROGS .. "/demos/cubeline/trunk/cubeline"}, {"3D/CUBELINE", PROGS .. "/demos/cubeline/trunk/cubeline"},
{"3D/GEARS", PROGS .. "/demos/gears/trunk/gears"}, {"3D/GEARS", PROGS .. "/demos/gears/trunk/gears"},
{"GAMES/CHECKERS", PROGS .. "/games/checkers/trunk/checkers"},
{"GAMES/REVERSI", PROGS .. "/games/reversi/trunk/reversi"}, {"GAMES/REVERSI", PROGS .. "/games/reversi/trunk/reversi"},
{"SHELL", PROGS .. "/system/shell/shell"}, {"SHELL", PROGS .. "/system/shell/shell"},
}) })

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -4,7 +4,11 @@
#undef assert #undef assert
#undef unimpl #undef unimpl
#ifdef NDEBUG
#define assert(test) /*nothing*/
#else
#define assert(test) ((void)((test)||(__dj_assert(#test,__FILE__,__LINE__),0))) #define assert(test) ((void)((test)||(__dj_assert(#test,__FILE__,__LINE__),0)))
#endif
#define unimpl() __dj_unimp("Called unimplemented function in file \"" __FILE__ "\"\n") #define unimpl() __dj_unimp("Called unimplemented function in file \"" __FILE__ "\"\n")
#ifndef __dj_include_assert_h_ #ifndef __dj_include_assert_h_

View File

@ -10,10 +10,7 @@ extern "C" {
#ifndef __dj_ENFORCE_ANSI_FREESTANDING #ifndef __dj_ENFORCE_ANSI_FREESTANDING
/* 65536(tics/hour) / 3600(sec/hour) * 5(scale) = 91.02 #define CLOCKS_PER_SEC 100
The 5 is to make it a whole number (18.2*5=91) so that
floating point ops aren't required to use it. */
#define CLOCKS_PER_SEC 91
#include <sys/djtypes.h> #include <sys/djtypes.h>

View File

@ -68,7 +68,7 @@ FOLDERS = {
"termios", "termios",
} }
CFLAGS="-Os -fno-stack-check -fno-stack-protector -mno-stack-arg-probe -fno-ident -fomit-frame-pointer -fno-asynchronous-unwind-tables -mpreferred-stack-boundary=2" CFLAGS="-Os -fno-stack-check -fno-stack-protector -mno-stack-arg-probe -fno-ident -fomit-frame-pointer -fno-asynchronous-unwind-tables -mpreferred-stack-boundary=2 -march=pentium-mmx"
OBJS={} OBJS={}
for i,v in ipairs(FOLDERS) do for i,v in ipairs(FOLDERS) do
tup.append_table(OBJS, tup.append_table(OBJS,

View File

@ -1,5 +1,6 @@
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
#include <stdio.h> #include <stdio.h>
#include <stdarg.h>
#include <libc/file.h> #include <libc/file.h>
int int

View File

@ -1,5 +1,6 @@
/* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */ /* Copyright (C) 1994 DJ Delorie, see COPYING.DJ for details */
#include <stdio.h> #include <stdio.h>
#include <stdarg.h>
#include <limits.h> #include <limits.h>
#include <libc/file.h> #include <libc/file.h>

View File

@ -36,7 +36,6 @@ extern char __menuet__app_param_area[];
void __crt1_startup(void) void __crt1_startup(void)
{ {
init_brk(); init_brk();
if(__menuet__app_param_area[0]!='\0')
__crt0_setup_arguments(); __crt0_setup_arguments();
dosemu_inithandles(); dosemu_inithandles();
init_dir_stack(); init_dir_stack();

View File

@ -6,5 +6,7 @@
clock_t clock(void) clock_t clock(void)
{ {
return 0; unsigned result;
__asm__ __volatile__("int $0x40" : "=a"(result) : "a"(26), "b"(9));
return result;
} }

View File

@ -1,5 +1,5 @@
if tup.getconfig('NO_GCC') ~= "" then return end if tup.getconfig('NO_GCC') ~= "" then return end
CFLAGS = "-Os -fno-stack-check -fno-stack-protector -mno-stack-arg-probe -fno-ident -fomit-frame-pointer -fno-asynchronous-unwind-tables -mpreferred-stack-boundary=2" CFLAGS = "-Os -fno-stack-check -fno-stack-protector -mno-stack-arg-probe -fno-ident -fomit-frame-pointer -fno-asynchronous-unwind-tables -mpreferred-stack-boundary=2 -march=pentium-mmx"
OBJS = tup.foreach_rule({"*.cpp", extra_inputs = {"../../config.h"}}, OBJS = tup.foreach_rule({"*.cpp", extra_inputs = {"../../config.h"}},
'kos32-gcc -c -I../../include -D__DEV_CONFIG_H=\\"../../config.h\\" ' .. CFLAGS .. " -o %o %f", 'kos32-gcc -c -I../../include -D__DEV_CONFIG_H=\\"../../config.h\\" ' .. CFLAGS .. " -o %o %f",
"%B.o") "%B.o")

View File

@ -1,5 +1,5 @@
if tup.getconfig('NO_GCC') ~= "" then return end if tup.getconfig('NO_GCC') ~= "" then return end
CFLAGS="-D_USE_LIBM_MATH_H -Os -fno-stack-check -fno-stack-protector -mno-stack-arg-probe -fno-ident -fomit-frame-pointer -fno-asynchronous-unwind-tables -mpreferred-stack-boundary=2" CFLAGS="-D_USE_LIBM_MATH_H -Os -fno-stack-check -fno-stack-protector -mno-stack-arg-probe -fno-ident -fomit-frame-pointer -fno-asynchronous-unwind-tables -mpreferred-stack-boundary=2 -march=pentium-mmx"
OBJS = tup.foreach_rule({"*.c", extra_inputs = {"../../config.h"}}, OBJS = tup.foreach_rule({"*.c", extra_inputs = {"../../config.h"}},
'kos32-gcc -c -I../../include -D__DEV_CONFIG_H=\\"../../config.h\\" ' .. CFLAGS .. ' -o %o %f', 'kos32-gcc -c -I../../include -D__DEV_CONFIG_H=\\"../../config.h\\" ' .. CFLAGS .. ' -o %o %f',
"%B.o") "%B.o")

View File

@ -28,7 +28,7 @@ static char rcsid[] = "$Id: k_standard.c,v 1.4 1994/08/10 20:31:44 jtc Exp $";
#undef fflush #undef fflush
#endif /* !defined(_USE_WRITE) */ #endif /* !defined(_USE_WRITE) */
inline int fputs(const char* str, FILE* f) { return -1; } #define fputs /*nothing*/
#ifdef __STDC__ #ifdef __STDC__
static const double zero = 0.0; /* used as const */ static const double zero = 0.0; /* used as const */

View File

@ -1,14 +1,12 @@
#ifndef _HEADER_BOARD_H #ifndef _HEADER_BOARD_H
#define _HEADER_BOARD_H #define _HEADER_BOARD_H
#ifndef __MENUET__
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
#include <math.h> #include <math.h>
#include <limits.h> #include <limits.h>
#endif
#include "position.h" #include "position.h"
#include "history.h" #include "history.h"
#include "gr-draw.h" #include "gr-draw.h"
@ -527,7 +525,7 @@ int TChBoard::GetTextLineY() const
return (y + height - delta_size.y) / 2; return (y + height - delta_size.y) / 2;
} }
#ifdef BUILD_RUS #ifdef LANG_RUS
#define aCheckersGame "ˆ£à  ¢ è èª¨." #define aCheckersGame "ˆ£à  ¢ è èª¨."
#define aRedMoves "Šà á­ë¥ 室ïâ." #define aRedMoves "Šà á­ë¥ 室ïâ."
#define aBlueMoves "‘¨­¨¥ 室ïâ." #define aBlueMoves "‘¨­¨¥ 室ïâ."

View File

@ -1,11 +1,9 @@
#ifndef _HEADER_BUTTONS_H #ifndef _HEADER_BUTTONS_H
#define _HEADER_BUTTONS_H #define _HEADER_BUTTONS_H
#ifndef __MENUET__
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <limits.h> #include <limits.h>
#endif
#include "gr-draw.h" #include "gr-draw.h"
struct TXButton struct TXButton

View File

@ -1,254 +1,32 @@
//#define LANG_RUS
#ifndef AUTOBUILD #define NDEBUG
#include "lang.h"
#endif
//#define BUILD_RUS
#ifndef __MENUET__
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
#include <math.h> #include <math.h>
#else
#include <menuet.h>
#include <me_heap.h>
using namespace Menuet;
#define strlen StrLen
#define strcpy StrCopy
#define memcpy MemCopy
#include <stdarg.h>
const unsigned dectab[] = { 1000000000, 100000000, 10000000, 1000000, 100000,
10000, 1000, 100, 10, 0 };
int sprintf( char *Str, char* Format, ... )
{
int i, fmtlinesize, j, k, flag;
unsigned head, tail;
char c;
va_list arglist;
//
va_start(arglist, Format);
// // sprintf is too heavy
fmtlinesize = strlen( Format ); int itoa(char* dst, int number)
//
if( fmtlinesize == 0 ) return 0;
//
for( i = 0, j = 0; i < fmtlinesize; i++ )
{
//
c = Format[i];
//
if( c != '%' )
{
Str[j++] = c;
continue;
}
//
i++;
//
if( i >= fmtlinesize ) break;
//
flag = 0;
//
c = Format[i];
if (c == 'l') c = Format[++i];
//
switch( c )
{
//
case '%':
Str[j++] = c;
break;
// <20>˜<EFBFBD><CB9C>„ Ÿ<><C5B8><EFBFBD>‰•
case 's':
char* str;
str = va_arg(arglist, char*);
for( k = 0; ( c = str[k] ) != 0; k++ )
{
Str[j++] = c;
}
break;
// <20>˜<EFBFBD><CB9C>„ Ÿ•<E280A2><E280B9>Šž
case 'c':
Str[j++] = va_arg(arglist, int) & 0xFF;
break;
// <20>˜<EFBFBD><CB9C>„ „<><E2809E>ˆŒ<CB86><EFBFBD> ŸŠ<C5B8><C5A0>ž <20> „…Ÿš<C5B8>Œ<E2809A> <20>•„…
case 'u':
case 'd':
head = va_arg(arglist, unsigned);
for( k = 0; dectab[k] != 0; k++ )
{
tail = head % dectab[k];
head /= dectab[k];
c = head + '0';
if( c == '0' )
{
if( flag ) Str[j++] = c;
}
else
{
flag++;
Str[j++] = c;
}
//
head = tail;
}
//
c = head + '0';
Str[j++] = c;
break;
default:
break;
}
}
//
Str[j] = 0;
return j;
}
int isdigit(int c)
{ {
return (c>='0' && c<='9'); int result = 0;
} if (number < 0) {
int atoi(const char* string) result++;
{ *dst++ = '-';
int res=0; number = -number;
int sign=0;
const char* ptr;
for (ptr=string; *ptr && *ptr<=' ';ptr++);
if (*ptr=='-') {sign=1;++ptr;}
while (*ptr >= '0' && *ptr <= '9')
{
res = res*10 + *ptr++ - '0';
} }
if (sign) res = -res; char digits[16];
return res; int ndigits = 0;
} do {
int islower(int c) digits[ndigits++] = number % 10;
{ number /= 10;
return (c>='a' && c<='z'); } while (number);
} result += ndigits;
int abs(int n) for (; ndigits--; )
{ *dst++ = digits[ndigits] + '0';
return (n<0)?-n:n; return result;
}
int memcmp(const void* buf1, const void* buf2, unsigned count)
{
const char* ptr1 = (const char*)buf1;
const char* ptr2 = (const char*)buf2;
unsigned i=0;
while (i<count && *ptr1==*ptr2) {++i;++ptr1;++ptr2;}
if (i==count)
return 0;
else if (*ptr1<*ptr2)
return -1;
else
return 1;
}
void strncpy(char* dest, const char* source, unsigned len)
{
char* ptr1 = dest;
const char *ptr2 = source;
for (;len-- && *ptr2; *ptr1++=*ptr2++) ;
}
unsigned int rand_data[4];
void randomize()
{
rand_data[0] = (unsigned int)Clock();
rand_data[1] = (unsigned int)GetPackedTime();
rand_data[2] = (unsigned int)GetPackedDate();
rand_data[3] = (unsigned int)0xA3901BD2 ^ GetPid();
} }
unsigned int rand()
{
rand_data[0] ^= _HashDword(rand_data[3] + 0x2835C013U);
rand_data[1] += _HashDword(rand_data[0]);
rand_data[2] -= _HashDword(rand_data[1]);
rand_data[3] ^= _HashDword(rand_data[2]);
return rand_data[3];
}
#define random(k) (rand() % (k))
#define floor Floor
double fabs(double x)
{
__asm fld x
__asm fabs
}
#define M_PI 3.14159265358979323846
double cos(double x)
{
__asm fld x
__asm fcos
}
double sin(double x)
{
__asm fld x
__asm fsin
}
/*inline void printf(const char* format, ...)
{}*/
#define printf /* nothing */
inline void strcat(char* str1, const char* str2)
{strcpy(str1+strlen(str1),str2);}
int strncmp(const char* str1, const char* str2, unsigned len)
{
for (;len--;)
{
if (*str1 != *str2) break;
if (*str1 == 0)
return 0;
++str1;++str2;
}
if (len==(unsigned)-1)
return 0;
if (*str1 < *str2)
return -1;
return 1;
}
#define clock Clock
typedef unsigned int clock_t;
#define CLOCKS_PER_SEC 100
#define XK_Left 0xB0
#define XK_Right 0xB3
#define XK_Up 0xB2
#define XK_Down 0xB1
#define XK_Return 0x0D
#define XK_space 0x20
#define XK_Escape 0x1B
#define XK_less '<'
#define XK_comma ','
#define XK_period '.'
#define XK_greater '>'
#define XK_minus '-'
#define XK_equal '='
#define XK_underscore '_'
#define XK_plus '+'
#define XK_Delete 0xB6
#define XK_F8 0x39
#define XK_l 'l'
#define XK_L 'L'
#define XK_F2 0x33
#define XK_s 's'
#define XK_S 'S'
#define XK_slash '/'
#define XK_question '?'
#define XK_n 'n'
#define XK_N 'N'
#define XK_t 't'
#define XK_T 'T'
#define XK_r 'r'
#define XK_R 'R'
#define XK_b 'b'
#define XK_B 'B'
#define XK_f 'f'
#define XK_F 'F'
#define assert(a) /* nothing */
#include "qsort.c"
#endif
#include "gr-draw.h" #include "gr-draw.h"
#include "board.h" #include "board.h"
#include "player.h" #include "player.h"
@ -272,7 +50,7 @@ public:
void Add(const PlayWrite &pl); void Add(const PlayWrite &pl);
PlayWrite &operator[](int i) {return play[i];} PlayWrite &operator[](int i) {return play[i];}
int GetNPlay() const {return nplay;} int GetNPlay() const {return nplay;}
#ifndef __MENUET__ #ifndef NO_FILES
int OpenFile(const char *name, int kind); int OpenFile(const char *name, int kind);
int MsgOpenFile(const char *name, int kind); int MsgOpenFile(const char *name, int kind);
int SaveFile(const char *name, int num, int kind); int SaveFile(const char *name, int num, int kind);
@ -285,7 +63,7 @@ protected:
PlayWrite *play; PlayWrite *play;
int nplay, mplay; int nplay, mplay;
protected: protected:
#ifndef __MENUET__ #ifndef NO_FILES
static const char *const search[]; static const char *const search[];
static int AnalizeKind(FILE *f, const int w[], const char *smb = 0); static int AnalizeKind(FILE *f, const int w[], const char *smb = 0);
static int ReadFileTo(FILE *f, char c); static int ReadFileTo(FILE *f, char c);
@ -294,8 +72,7 @@ protected:
#endif #endif
}; };
#ifndef __MENUET__ #ifdef LANG_RUS //Pending Russian Translations
#if LANG_RUS //Pending Russian Translations
#define CHECKERS_CANT_OPEN_STR "\n˜ èª¨: <20>¥ ¬®£ã ®âªàëâì ä ©« \"%s\".\n" #define CHECKERS_CANT_OPEN_STR "\n˜ èª¨: <20>¥ ¬®£ã ®âªàëâì ä ©« \"%s\".\n"
#define CHECKERS_FILE_EMPTY_STR "\n˜ èª¨: ” ©« \"%s\" ¯ãáâ.\n" #define CHECKERS_FILE_EMPTY_STR "\n˜ èª¨: ” ©« \"%s\" ¯ãáâ.\n"
#define CHECKERS_INVALID_FILE_STR "\n˜ èª¨: ” ©« \"%s\" ®è¨¡®ç­ë©.\n" #define CHECKERS_INVALID_FILE_STR "\n˜ èª¨: ” ©« \"%s\" ®è¨¡®ç­ë©.\n"
@ -325,8 +102,10 @@ protected:
#define EXIT_STR "exit" #define EXIT_STR "exit"
#define CHECKERS_INVALID_STR "Checkers: Invalid key %s\n" #define CHECKERS_INVALID_STR "Checkers: Invalid key %s\n"
#ifndef NO_FILES
const char *const TPlayArray::search[] = const char *const TPlayArray::search[] =
{"checkers-", "play:", "text", "bin_1.0\n", "history_", "1.0", "1.1"}; {"checkers-", "play:", "text", "bin_1.0\n", "history_", "1.0", "1.1"};
#endif
#else /*For all other languages except RUS*/ #else /*For all other languages except RUS*/
#define CHECKERS_CANT_OPEN_STR "\nCheckers: Can't open the file \"%s\".\n" #define CHECKERS_CANT_OPEN_STR "\nCheckers: Can't open the file \"%s\".\n"
@ -357,10 +136,12 @@ const char *const TPlayArray::search[] =
#define ROTATE_BOARD_STR "rotate board" #define ROTATE_BOARD_STR "rotate board"
#define EXIT_STR "exit" #define EXIT_STR "exit"
#define CHECKERS_INVALID_STR "Checkers: Invalid key %s\n" #define CHECKERS_INVALID_STR "Checkers: Invalid key %s\n"
#ifndef NO_FILES
const char *const TPlayArray::search[] = const char *const TPlayArray::search[] =
{"checkers-", "play:", "text", "bin_1.0\n", "history_", "1.0", "1.1"}; {"checkers-", "play:", "text", "bin_1.0\n", "history_", "1.0", "1.1"};
#endif #endif
#endif #endif
void TPlayArray::Clear() void TPlayArray::Clear()
{ {
@ -392,7 +173,7 @@ void TPlayArray::Add(const PlayWrite &pl)
nplay++; nplay++;
} }
#ifndef __MENUET__ #ifndef NO_FILES
int TPlayArray::AnalizeKind(FILE *f, const int w[], const char *smb) int TPlayArray::AnalizeKind(FILE *f, const int w[], const char *smb)
{ {
int i, L, was1 = 1; int i, L, was1 = 1;
@ -880,22 +661,22 @@ protected:
void TMainDraw::InitButton() void TMainDraw::InitButton()
{ {
char newgame_literal[] = NEW_GAME_STR; static char newgame_literal[] = NEW_GAME_STR;
char list_literal[] = LIST_STR; static char list_literal[] = LIST_STR;
char delete_literal[] = DELETE_STR; static char delete_literal[] = DELETE_STR;
char clear_literal[] = CLEAR_STR; static char clear_literal[] = CLEAR_STR;
char save_literal[] = SAVE_STR; static char save_literal[] = SAVE_STR;
char rotateboard_literal[] = ROTATE_BOARD_STR; static char rotateboard_literal[] = ROTATE_BOARD_STR;
char exit_literal[] = EXIT_STR; static char exit_literal[] = EXIT_STR;
char one_literal[] = "1"; static char one_literal[] = "1";
char dash_literal[] = "-"; static char dash_literal[] = "-";
char plus_literal[] = "+"; static char plus_literal[] = "+";
char leftshift_literal[] = "<<"; static char leftshift_literal[] = "<<";
char rightshift_literal[] = ">>"; static char rightshift_literal[] = ">>";
char lessthan_literal[] = "<"; static char lessthan_literal[] = "<";
char greaterthan_literal[] = ">"; static char greaterthan_literal[] = ">";
char xor_literal[] = "^"; static char xor_literal[] = "^";
button.Add(1, 80, 22, newgame_literal); button.Add(1, 80, 22, newgame_literal);
button.Add(6, 60, 22, list_literal); button.Add(6, 60, 22, list_literal);
@ -909,7 +690,7 @@ void TMainDraw::InitButton()
play_list->SetDefW(); play_list->SetDefW();
button.Add(play_list); button.Add(play_list);
button.Add(24, 50, 22, clear_literal); button.Add(24, 50, 22, clear_literal);
#ifndef __MENUET__ #ifndef NO_FILES
button.Add(25, 50, 22, save_literal); button.Add(25, 50, 22, save_literal);
#endif #endif
button.Add(2, 120, 22, player_str[0]); button.Add(2, 120, 22, player_str[0]);
@ -970,7 +751,7 @@ void TMainDraw::SetButtonKind(const TChBoard &board)
if (bt1) bt1->drw = is_drw; if (bt1) bt1->drw = is_drw;
bt1 = button.GetButton(7); bt1 = button.GetButton(7);
if (bt1) bt1->drw = !is_drw; if (bt1) bt1->drw = !is_drw;
#ifndef __MENUET__ #ifndef NO_FILES
bt1 = button.GetButton(25); bt1 = button.GetButton(25);
if (bt1) bt1->drw = !is_drw; if (bt1) bt1->drw = !is_drw;
#endif #endif
@ -982,20 +763,18 @@ void TMainDraw::SetButtonKind(const TChBoard &board)
if (is_drw) if (is_drw)
{ {
play_num[0][0] = 0; play_num[1][0] = 0; play_num[0][0] = 0; play_num[1][0] = 0;
if (cur_play >= 0) sprintf(play_num[0], "%d", cur_play + 1); if (cur_play >= 0) itoa(play_num[0], cur_play + 1);
sprintf(play_num[1], "%d", play.GetNPlay()); itoa(play_num[1], play.GetNPlay());
thick = (cur_play <= 0) ? 0 : 3; thick = (cur_play <= 0) ? 0 : 3;
#define dynamic_cast static_cast txb = static_cast<TextButton*>(play_list->a.GetButton(21));
txb = dynamic_cast<TextButton*>(play_list->a.GetButton(21));
if (txb) txb->thick = thick; if (txb) txb->thick = thick;
txb = dynamic_cast<TextButton*>(play_list->a.GetButton(26)); txb = static_cast<TextButton*>(play_list->a.GetButton(26));
if (txb) txb->thick = thick; if (txb) txb->thick = thick;
thick = (cur_play >= play.GetNPlay() - 1) ? 0 : 3; thick = (cur_play >= play.GetNPlay() - 1) ? 0 : 3;
txb = dynamic_cast<TextButton*>(play_list->a.GetButton(22)); txb = static_cast<TextButton*>(play_list->a.GetButton(22));
if (txb) txb->thick = thick; if (txb) txb->thick = thick;
txb = dynamic_cast<TextButton*>(play_list->a.GetButton(27)); txb = static_cast<TextButton*>(play_list->a.GetButton(27));
if (txb) txb->thick = thick; if (txb) txb->thick = thick;
#undef dynamic_cast
} }
} }
@ -1073,7 +852,7 @@ void TMainDraw::PressLS(int n, TChBoard &board, TGraphDraw *drw)
} }
} }
else if (n == 24) {play.Clear(); cur_play = 0; need_redraw = 1;} else if (n == 24) {play.Clear(); cur_play = 0; need_redraw = 1;}
#ifndef __MENUET__ #ifndef NO_FILES
else if (n == 25) else if (n == 25)
{ {
if (play.GetNPlay() > 0) play.MsgSaveFile(def_savefile, -1, def_savekind); if (play.GetNPlay() > 0) play.MsgSaveFile(def_savefile, -1, def_savekind);
@ -1313,7 +1092,7 @@ int TMainData::EventFunction(const TGraphDraw::event &ev)
else if (ev.key.k == XK_Delete) data.main_draw.PressLS(7, data.board, ev.button.drw); else if (ev.key.k == XK_Delete) data.main_draw.PressLS(7, data.board, ev.button.drw);
else if (ev.key.k == XK_F8) data.main_draw.PressLS(24, data.board, ev.button.drw); else if (ev.key.k == XK_F8) data.main_draw.PressLS(24, data.board, ev.button.drw);
else if (ev.key.k == XK_l || ev.key.k == XK_L) data.main_draw.PressLS(6, data.board, ev.button.drw); else if (ev.key.k == XK_l || ev.key.k == XK_L) data.main_draw.PressLS(6, data.board, ev.button.drw);
#ifndef __MENUET__ #ifndef NO_FILES
else if (ev.key.k == XK_F2) data.main_draw.PressLS(25, data.board, ev.button.drw); else if (ev.key.k == XK_F2) data.main_draw.PressLS(25, data.board, ev.button.drw);
#endif #endif
else if (ev.key.k == XK_s || ev.key.k == XK_S) data.main_draw.PressLS(28, data.board, ev.button.drw); else if (ev.key.k == XK_s || ev.key.k == XK_S) data.main_draw.PressLS(28, data.board, ev.button.drw);
@ -1342,11 +1121,12 @@ int TMainData::EventFunction(const TGraphDraw::event &ev)
return ret; return ret;
} }
#ifndef __MENUET__
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
randomize(); randomize();
#ifndef NO_FILES
THistory::InitHFile(argv[0]); THistory::InitHFile(argv[0]);
#endif
TMainData data(-1); TMainData data(-1);
if (argv && argc >= 2) if (argv && argc >= 2)
{ {
@ -1376,7 +1156,9 @@ int main(int argc, char **argv)
} }
else if (kx == 0 || kx == 1) else if (kx == 0 || kx == 1)
{ {
#ifndef NO_FILES
data.main_draw.play.MsgOpenFile(argv[i], -1); data.main_draw.play.MsgOpenFile(argv[i], -1);
#endif
} }
} }
} }
@ -1391,65 +1173,3 @@ int main(int argc, char **argv)
450 + 100 * ssf, 528); 450 + 100 * ssf, 528);
return 0; return 0;
} }
#else
TMainData* mdata;
TMainGraphDraw* graph;
bool MenuetOnStart(TStartData &me_start, TThreadData)
{
mdata = new TMainData(-1);
graph = new TMainGraphDraw;
randomize();
mdata->InitDef();
static TTimerDraw timer_draw(&mdata->board, graph);
mdata->player.draw = TTimerDraw::draw; mdata->player.data = &timer_draw;
graph->data = mdata;
me_start.WinData.Title = CHECKERS_STR;
me_start.Width = 450 + 100*ssf;
me_start.Height = 528;
return true;
}
bool MenuetOnClose(TThreadData)
{
delete mdata;
delete graph;
return true;
}
int MenuetOnIdle(TThreadData)
{return -1;}
void MenuetOnSize(int window_rect[], TThreadData)
{mdata->board.Resize(window_rect[2]-window_rect[0], window_rect[3]-window_rect[1]);}
void MenuetOnKeyPress(TThreadData)
{
TGraphDraw::event ev;
ev.type = TGraphDraw::event::key_down;
ev.any.drw = graph;
ev.key.k = GetKey();
mdata->EventFunction(ev);
}
void MenuetOnDraw(void)
{
TGraphDraw::event ev;
ev.type = TGraphDraw::event::draw;
ev.any.drw = graph;
mdata->EventFunction(ev);
}
void MenuetOnMouse(TThreadData)
{
short x,y;
GetMousePosition(x,y);
int m = GetMouseButton() & 1;
static int mprev = 0;
if (m == mprev)
return;
mprev = m;
TGraphDraw::event ev;
ev.type = m ? TGraphDraw::event::button_down : TGraphDraw::event::button_up;
ev.any.drw = graph;
ev.button.n = 1;
ev.button.x = x;
ev.button.y = y;
mdata->EventFunction(ev);
}
#endif

View File

@ -1,18 +1,13 @@
1. Компиляция под Колибри. 1. Компиляция под Колибри.
Для компиляции необходим Borland C++ (из всего пакета нужен только компилятор Стандартная для программ, использующих menuetlibc.
командной строки), а также FASM версии не более 1.64.
cpp2asm.bat компилирует С++-исходник в TASM-исходник,
а потом превращает его в FASM-исходник.
После этого, возможно, понадобится перенести в f_checkers.asm строки с equ
в начало файла.
Компиляция бинарника - как обычно, fasm f_checkers.asm checkers.
2. Компиляция под Linux. 2. Компиляция под Linux.
Просто скажите make. По крайней мере в одной Linux-системе это работает. Просто скажите make. По крайней мере в одной Linux-системе это работает.
В других могут понадобиться некоторые изменения. В других могут понадобиться некоторые изменения.
В исходниках русские буквы записаны в кодировке DOS (cp866). Так что для В исходниках русские буквы записаны в кодировке DOS (cp866). Так что для
вразумительных сообщений либо закомментируйте первую строку в checkers.cpp вразумительных сообщений на русском нужно, помимо раскомментирования первой
("#define BUILD_RUS"), либо прогоните все *.cpp и *.h файлы через dos2unix. строки в checkers.cpp ("#define LANG_RUS"),
ещё прогнать все *.cpp и *.h файлы через dos2unix.
3. Компиляция под DOS/Windows. 3. Компиляция под DOS/Windows.
Для компиляции необходим пакет Borland C++ for DOS/Windows соответственно. Для компиляции необходим пакет Borland C++ for DOS/Windows соответственно.

View File

@ -1,7 +0,0 @@
del *.o
echo #define LANG_ENG 1 > lang.h
g++ -c checkers.cpp
g++ -L/usr/X11R6/lib -lX11 -o checkers checkers.o
pause

View File

@ -1,7 +0,0 @@
del *.o
echo #define LANG_RUS 1 > lang.h
g++ -c checkers.cpp
g++ -L/usr/X11R6/lib -lX11 -o checkers checkers.o
pause

View File

@ -1,3 +0,0 @@
bcc32 -S -v- -R- -6 -a4 -O2 -Og -Oi -Ov -OS -k- -x- -D__MENUET__ -Iinclude checkers.cpp
echo include "me_make.inc" > f_checkers.asm
t2fasm < checkers.asm >> f_checkers.asm

View File

@ -10,8 +10,9 @@
#include <stdio.h> #include <stdio.h>
#include <limits.h> #include <limits.h>
class TDosGraphDraw : public TGraphDraw class TDosGraphDraw : public TBaseGraphDraw<TDosGraphDraw>
{ {
typedef TBaseGraphDraw<TDosGraphDraw> TGraphDraw;
public: public:
TDosGraphDraw(const char *s = 0); TDosGraphDraw(const char *s = 0);
~TDosGraphDraw() {} ~TDosGraphDraw() {}

View File

@ -8,8 +8,9 @@
#ifndef _GNU_GRAPHIC_DRAW_H #ifndef _GNU_GRAPHIC_DRAW_H
#define _GNU_GRAPHIC_DRAW_H #define _GNU_GRAPHIC_DRAW_H
class TGnuGraphDraw : public TGraphDraw class TGnuGraphDraw : public TBaseGraphDraw<TGnuGraphDraw>
{ {
typedef TBaseGraphDraw<TGnuGraphDraw> TGraphDraw;
public: public:
TGnuGraphDraw(const char *s = 0); TGnuGraphDraw(const char *s = 0);
~TGnuGraphDraw(); ~TGnuGraphDraw();

View File

@ -1,19 +1,15 @@
#ifndef _GRAPHIC_DRAW_H #ifndef _GRAPHIC_DRAW_H
#define _GRAPHIC_DRAW_H #define _GRAPHIC_DRAW_H
#ifndef __MENUET__
#include <limits.h> #include <limits.h>
#include <string.h> #include <string.h>
#ifdef _Windows #ifdef _Windows
# include <windows.h> # include <windows.h>
#endif #endif
#else
#define LONG_MIN (-2147483647L-1) /* minimum signed long value */
#define INT_MIN LONG_MIN
#endif
class TGraphDraw template<class TRealGraphDraw>
class TBaseGraphDraw
{ {
public: public:
union event union event
@ -24,7 +20,7 @@ public:
struct evany struct evany
{ {
evtype type; evtype type;
TGraphDraw *drw; TRealGraphDraw *drw;
} any; } any;
struct evbutton : public evany struct evbutton : public evany
@ -43,41 +39,41 @@ public:
enum {ret_setcapture = 0x10}; enum {ret_setcapture = 0x10};
public: public:
TGraphDraw(const char *s = 0) : title(0), about_info(0), TBaseGraphDraw(const char *s = 0) : title(0), about_info(0),
evfunc(0), id(0), data(0) {CopyTitle(s);} evfunc(0), id(0), data(0) {CopyTitle(s);}
~TGraphDraw() {FreeTitle();} ~TBaseGraphDraw() {FreeTitle();}
virtual unsigned long GetBlackColor() {return 0;} unsigned long GetBlackColor() {return 0;}
virtual unsigned long GetWhiteColor() {return 0xFFFFFFL;} unsigned long GetWhiteColor() {return 0xFFFFFFL;}
virtual unsigned long CreateColor(unsigned short red, unsigned long CreateColor(unsigned short red,
unsigned short green, unsigned short blue); unsigned short green, unsigned short blue);
virtual void FreeColor(unsigned long c) {} void FreeColor(unsigned long c) {}
virtual unsigned long GetBgColor() {return GetWhiteColor();} unsigned long GetBgColor() {return GetWhiteColor();}
virtual void SetBgColor(unsigned long c) {} void SetBgColor(unsigned long c) {}
virtual void SetTitle(const char *s) {CopyTitle(s);} void SetTitle(const char *s) {CopyTitle(s);}
const char *GetTitle() const {return title;} const char *GetTitle() const {return title;}
virtual int GetStatus() {return 0;} //1 - can draw, 0 - can't draw, <0 - error int GetStatus() {return 0;} //1 - can draw, 0 - can't draw, <0 - error
virtual int Init() {return 0;} int Init() {return 0;}
virtual void UnInit() {} void UnInit() {}
virtual int Run(int evmask = 0, int w = INT_MIN, int h = INT_MIN) {return -100;} int Run(int evmask = 0, int w = INT_MIN, int h = INT_MIN) {return -100;}
virtual void GetSize(int &w, int &h) {w = 200; h = 200;} void GetSize(int &w, int &h) {w = 200; h = 200;}
virtual int OpenDraw() {return 0;} int OpenDraw() {return 0;}
virtual int IsDraw() {return 0;} int IsDraw() {return 0;}
virtual void CloseDraw() {} void CloseDraw() {}
virtual int SetColor(unsigned long c) {return 0;} int SetColor(unsigned long c) {return 0;}
virtual int DrawLine(int x0, int y0, int x1, int y1) {return 0;} int DrawLine(int x0, int y0, int x1, int y1) {return 0;}
virtual int DrawText(int x0, int y0, char *text) {return 0;} int DrawText(int x0, int y0, char *text) {return 0;}
virtual int DrawClear() {return 0;} int DrawClear() {return 0;}
virtual int GetTextH(const char *s) {return 16;} int GetTextH(const char *s) {return 16;}
virtual int GetTextW(const char *s) {return 8 * strlen(s);} int GetTextW(const char *s) {return 8 * strlen(s);}
virtual void Quit(int q = 1) {} void Quit(int q = 1) {}
virtual void ResReinit(int w = INT_MIN, int h = INT_MIN) {} void ResReinit(int w = INT_MIN, int h = INT_MIN) {}
virtual int GetAboutInfo() {return about_info;} int GetAboutInfo() {return about_info;}
virtual void SetAboutInfo(int inf) {about_info = inf;} void SetAboutInfo(int inf) {about_info = inf;}
protected: protected:
void FreeTitle() {if (title) {delete[] title; title = 0;}} void FreeTitle() {if (title) {delete[] title; title = 0;}}
void CopyTitle(const char *s); void CopyTitle(const char *s);
@ -89,25 +85,27 @@ public:
void *data; void *data;
}; };
unsigned long TGraphDraw::CreateColor(unsigned short red, template<class TRealGraphDraw>
unsigned long TBaseGraphDraw<TRealGraphDraw>::CreateColor(unsigned short red,
unsigned short green, unsigned short blue) unsigned short green, unsigned short blue)
{ {
return (unsigned long)(red >> 8) + ((unsigned long)(green >> 8) << 8) + return (unsigned long)(red >> 8) + ((unsigned long)(green >> 8) << 8) +
((unsigned long)(blue >> 8) << 16); ((unsigned long)(blue >> 8) << 16);
} }
void TGraphDraw::CopyTitle(const char *s) template<class TRealGraphDraw>
void TBaseGraphDraw<TRealGraphDraw>::CopyTitle(const char *s)
{ {
FreeTitle(); FreeTitle();
if (s) {title = new char[strlen(s) + 1]; strcpy(title, s);} if (s) {title = new char[strlen(s) + 1]; strcpy(title, s);}
} }
#if defined __GNUC__ #if defined _KOLIBRI
# include "kolibri-draw.h"
typedef TKlbrGraphDraw TMainGraphDraw;
#elif defined __GNUC__
# include "gnu-draw.h" # include "gnu-draw.h"
typedef TGnuGraphDraw TMainGraphDraw; typedef TGnuGraphDraw TMainGraphDraw;
#elif defined __MENUET__
# include "mt-draw.h"
typedef TKlbrGraphDraw TMainGraphDraw;
#elif defined _Windows #elif defined _Windows
# include "win-draw.h" # include "win-draw.h"
typedef TWinGraphDraw TMainGraphDraw; typedef TWinGraphDraw TMainGraphDraw;
@ -115,7 +113,8 @@ void TGraphDraw::CopyTitle(const char *s)
# include "dos-draw.h" # include "dos-draw.h"
typedef TDosGraphDraw TMainGraphDraw; typedef TDosGraphDraw TMainGraphDraw;
#else #else
typedef TGraphDraw TMainGraphDraw; #error "Unknown platform"
#endif #endif
typedef TMainGraphDraw TGraphDraw;
#endif //_GRAPHIC_DRAW_H #endif //_GRAPHIC_DRAW_H

View File

@ -1,19 +1,13 @@
#ifndef _HEADER_HISTORY_H #ifndef _HEADER_HISTORY_H
#define _HEADER_HISTORY_H #define _HEADER_HISTORY_H
#ifndef __MENUET__
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#endif
#include "position.h" #include "position.h"
#include "hash.h" #include "hash.h"
#include "sysproc.h" #include "sysproc.h"
class THistory class THistory
{ {
#ifndef __MENUET__ #ifndef NO_FILES
public: public:
static char FileName[1024]; static char FileName[1024];
#endif #endif
@ -27,7 +21,7 @@ public:
int Move(const Position &pos, const unsigned char mv[], int nmove) const; int Move(const Position &pos, const unsigned char mv[], int nmove) const;
int Play(const PlayWrite &play) const; int Play(const PlayWrite &play) const;
#ifndef __MENUET__ #ifndef NO_FILES
static int InitHFile(char *dname = 0); static int InitHFile(char *dname = 0);
static int HRead(FILE *f, PlayWrite *&play); static int HRead(FILE *f, PlayWrite *&play);
protected: protected:
@ -119,12 +113,12 @@ protected:
}; };
}; };
#ifndef __MENUET__ #ifndef NO_FILES
char THistory::FileName[1024] = "history.che"; char THistory::FileName[1024] = "history.che";
#endif #endif
int THistory::NHid = 0; int THistory::NHid = 0;
#ifndef __MENUET__ #ifndef NO_FILES
int THistory::Print(const char *str) const int THistory::Print(const char *str) const
{ {
char *line = new char[30 + strlen(str)]; char *line = new char[30 + strlen(str)];
@ -150,9 +144,9 @@ int THistory::Print(const char *str) const
int THistory::Start(const Position &pos) const int THistory::Start(const Position &pos) const
{ {
#ifndef NO_FILES
char str[20 + NUM_CELL] = "Start "; char str[20 + NUM_CELL] = "Start ";
if (!pos.Write(str + strlen(str), 1)) return 0; if (!pos.Write(str + strlen(str), 1)) return 0;
#ifndef __MENUET__
if (!Print(str)) return 0; if (!Print(str)) return 0;
#endif #endif
return 1; return 1;
@ -160,14 +154,14 @@ int THistory::Start(const Position &pos) const
int THistory::Move(const Position &pos, const unsigned char mv[], int nmove) const int THistory::Move(const Position &pos, const unsigned char mv[], int nmove) const
{ {
#ifndef NO_FILES
char *str = new char[15 + pos.GetLenMvEx(mv, 11)]; char *str = new char[15 + pos.GetLenMvEx(mv, 11)];
if (!str) return 0; if (!str) return 0;
sprintf(str, "%d.%s ", (nmove + 1) / 2, (nmove % 2 == 0) ? ".." : ""); sprintf(str, "%d.%s ", (nmove + 1) / 2, (nmove % 2 == 0) ? ".." : "");
pos.WriteMvEx(mv, str + strlen(str), 11); pos.WriteMvEx(mv, str + strlen(str), 11);
#ifndef __MENUET__
if (!Print(str)) {delete[] str; return 0;} if (!Print(str)) {delete[] str; return 0;}
#endif
delete[] str; delete[] str;
#endif
return 1; return 1;
} }
@ -188,7 +182,7 @@ int THistory::Play(const PlayWrite &play) const
return 1; return 1;
} }
#ifndef __MENUET__ #ifndef NO_FILES
int THistory::InitHFile(char *dname) int THistory::InitHFile(char *dname)
{ {
if (dname && dname[0]) if (dname && dname[0])
@ -262,7 +256,7 @@ int THistory::THash::operator()(const TStr &str) const
return r; return r;
} }
#ifndef __MENUET__ #ifndef NO_FILES
int THistory::HRead(FILE *f, PlayWrite *&play) int THistory::HRead(FILE *f, PlayWrite *&play)
{ {
const int MAX_INP_WORD = 100; const int MAX_INP_WORD = 100;

File diff suppressed because it is too large Load Diff

View File

@ -1,90 +0,0 @@
#ifndef __MENUET_HEAP_H_INCLUDED_
#define __MENUET_HEAP_H_INCLUDED_
#include <menuet.h>
#include <memheap.h>
// Menuet memory heap interface.
namespace Menuet // All menuet functions, types and data are nested in the (Menuet) namespace.
{
void *Alloc(unsigned int size);
void *ReAlloc(void *mem, unsigned int size);
void Free(void *mem);
}
#ifdef __MENUET__
namespace Menuet
{
// Global variables
MemoryHeap::TFreeSpace _MenuetFreeSpace;
MemoryHeap::TMemBlock _MenuetMemBlock;
TMutex _MemHeapMutex = MENUET_MUTEX_INIT;
// Functions
void *_HeapInit(void *begin, void *use_end, void *end)
{
MemoryHeap::InitFreeSpace(_MenuetFreeSpace);
_MenuetMemBlock = MemoryHeap::CreateBlock(begin, end, _MenuetFreeSpace);
unsigned int use_beg = (unsigned int)MemoryHeap::BlockBegin(_MenuetMemBlock) +
MemoryHeap::BlockAddSize - MemoryHeap::BlockEndSize;
unsigned int use_size = (unsigned int)use_end;
if (use_size <= use_beg) return 0;
else use_size -= use_beg;
return MemoryHeap::Alloc(_MenuetFreeSpace, use_size);
}
bool _SetUseMemory(unsigned int use_mem);
int _RecalculateUseMemory(unsigned int use_mem);
void *Alloc(unsigned int size)
{
if (!size) return 0;
Lock(&_MemHeapMutex);
void *res = MemoryHeap::Alloc(_MenuetFreeSpace, size);
if (!res)
{
unsigned use_mem = (unsigned int)MemoryHeap::BlockEndFor(_MenuetMemBlock, size);
if (_SetUseMemory(_RecalculateUseMemory(use_mem)))
{
res = MemoryHeap::Alloc(_MenuetFreeSpace, size);
}
}
UnLock(&_MemHeapMutex);
return res;
}
void *ReAlloc(void *mem, unsigned int size)
{
Lock(&_MemHeapMutex);
void *res = MemoryHeap::ReAlloc(_MenuetFreeSpace, mem, size);
if (!res && size)
{
unsigned use_mem = (unsigned int)MemoryHeap::BlockEndFor(_MenuetMemBlock, size);
if (_SetUseMemory(_RecalculateUseMemory(use_mem)))
{
res = MemoryHeap::ReAlloc(_MenuetFreeSpace, mem, size);
}
}
UnLock(&_MemHeapMutex);
return res;
}
void Free(void *mem)
{
Lock(&_MemHeapMutex);
MemoryHeap::Free(_MenuetFreeSpace, mem);
UnLock(&_MemHeapMutex);
}
void _FreeAndThreadFinish(void *mem, int *exit_proc_now);
}
#endif // def __MENUET__
#endif // ndef __MENUET_HEAP_H_INCLUDED_

View File

@ -1,284 +0,0 @@
;/***
MenuetHeapInit = @@Menuet@_HeapInit$qpvt1t1
MenuetHeapAlloc = @@Menuet@Alloc$qui
MenuetHeapReAlloc = @@Menuet@ReAlloc$qpvui
MenuetHeapFree = @@Menuet@Free$qpv
MenuetHeapFreeAndThreadFinish = @Menuet@_FreeAndThreadFinish$qpvpi
define @Menuet@_SetUseMemory$qui
push ebx
mov eax,64
mov ebx,1
mov ecx,[esp+8]
int 0x40
pop ebx
test eax,eax
jnz Menuet_set_use_memory_nomem
push ecx
push dword [@Menuet@_MenuetMemBlock]
call @@MemoryHeap@ResizeBlock$q20MemoryHeap@TMemBlockpv
add esp,8
mov al,1
ret
Menuet_set_use_memory_nomem:
xor al,al
ret
enddef
define @Menuet@_RecalculateUseMemory$qui
mov eax,dword [esp+4]
mov ecx,(U_END + 3) and not 3
cmp eax,ecx
jna Menuet_recalculate_use_memory_min
push ebx
sub eax,ecx
mov ebx,6
mul ebx
dec ebx
div ebx
add eax,((U_END + 3) and not 3) + 3
and eax,not 3
pop ebx
ret
Menuet_recalculate_use_memory_min:
mov eax,ecx
ret
enddef
define @Menuet@_FreeAndThreadFinish$qpvpi
mov ebx,1
mov ecx,[esp+8]
jmp Menuet_heap_free_tf_wait
Menuet_heap_free_tf_wait_loop:
mov eax,5
int 0x40
shl ebx,1
cmp ebx,MENUET_MUTEX_MAX_TIME_WAIT
jna Menuet_heap_free_tf_wait
mov ebx,MENUET_MUTEX_MAX_TIME_WAIT
Menuet_heap_free_tf_wait:
cmp dword [ecx],0
jnz @Menuet@ExitProcess$qv
lock bts dword [@Menuet@_MemHeapMutex],0
jc Menuet_heap_free_tf_wait_loop
push dword [esp+4]
push @Menuet@_MenuetFreeSpace
call @@MemoryHeap@Free$qr21MemoryHeap@TFreeSpacepv
add esp,8
mov byte [@Menuet@_MemHeapMutex],0x40
or eax,-1
int 0x40
enddef
macro call func
{
if func eq @MemoryHeap@_FirstNotZeroBit$qui
bsf eax,[esp]
else if func eq @MemoryHeap@_CopyMemItemArray$quiuiui
xchg edi,[esp]
xchg esi,[esp+4]
mov ecx,[esp+8]
cld
sub ecx,esi
shr ecx,2
rep movs dword [edi],[esi]
xchg edi,[esp]
xchg esi,[esp+4]
else
call func
end if
}
@$bnwa$qui = @@Menuet@Alloc$qui
@$bnew$qui = @@Menuet@Alloc$qui
@$bdla$qpv = @@Menuet@Free$qpv
@$bdele$qpv = @@Menuet@Free$qpv
define @_vector_new_ldtc_$qpvuiuiuit1uit1
.var_2C = -0Ch
.var_28 = -8
.var_24 = -4
.arg_0 = 8
.arg_4 = 0Ch
.arg_8 = 10h
.arg_C = 14h
.arg_10 = 18h
push ebp
mov ebp, esp
add esp, -0Ch
push ebx
push esi
push edi
mov edi, [ebp+.arg_10]
mov esi, [ebp+.arg_C]
cmp dword [ebp+.arg_0], 0
jnz .loc_10070
mov edx, [ebp+.arg_4]
imul edx, [ebp+.arg_8]
test esi, 10h
jz @f
add edx, 4
@@:
push edx
call @$bnwa$qui
pop ecx
mov [ebp+.arg_0], eax
test eax, eax
jz .ret
mov dword [ebp+.var_2C], 1
jmp @f
.loc_10070:
and dword [ebp+.var_2C], 0
@@:
test esi, 10h
jz @f
mov edx, [ebp+.arg_0]
mov ecx, [ebp+.arg_8]
mov [edx], ecx
add dword [ebp+.arg_0], 4
@@:
mov eax, [ebp+.arg_0]
test edi, edi
jz .ret
mov ecx, [ebp+.arg_8]
mov [ebp+.var_28], ecx
mov ebx, eax
jmp .loc_100EF
.loc_100B0:
mov eax, esi
and eax, 7
dec eax
jz .loc_100CB
dec eax
jz .loc_100D1
dec eax
jz .loc_100D6
dec eax
dec eax
jz .loc_100DC
jmp $
.loc_100CB:
push ebx
call edi
pop ecx
jmp .loc_100EC
.loc_100D1:
.loc_100DC:
push ebx
call edi
jmp .loc_100EC
.loc_100D6:
mov eax, ebx
call edi
.loc_100EC:
add ebx, [ebp+.arg_4]
.loc_100EF:
dec dword [ebp+.var_28]
jns .loc_100B0
mov eax, [ebp+.arg_0]
.ret:
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret
enddef
define @_vector_delete_ldtc_$qpvuiuiuit1
.arg_0 = 8
.arg_4 = 0Ch
.arg_8 = 10h
.arg_C = 14h
.arg_10 = 18h
push ebp
mov ebp, esp
push ebx
push esi
push edi
mov edi, [ebp+.arg_C]
mov esi, edi
and esi, 10h
and edi, 8
cmp dword [ebp+.arg_0], 0
jz .ret
test esi, esi
jz @f
mov ecx, [ebp+.arg_0]
mov eax, [ecx-4]
mov [ebp+.arg_8], eax
@@:
mov ebx, [ebp+.arg_8]
dec ebx
imul ebx, [ebp+.arg_4]
add ebx, [ebp+.arg_0]
jmp .loc_100D3
.loc_1008B:
mov eax, [ebp+.arg_C]
and eax, 7
dec eax
jz .loc_1009E
dec eax
jz .loc_100A9
dec eax
jz .loc_100B1
dec eax
dec eax
jz .loc_100BD
jmp $
.loc_1009E:
push 2
push ebx
call dword [ebp+.arg_10]
add esp, 8
jmp .loc_100D0
.loc_100A9:
push 2
push ebx
call dword [ebp+.arg_10]
jmp .loc_100D0
.loc_100B1:
mov edx, 2
mov eax, ebx
call dword [ebp+.arg_10]
jmp .loc_100D0
.loc_100BD:
push 2
push ebx
call dword [ebp+.arg_10]
.loc_100D0:
sub ebx, [ebp+.arg_4]
.loc_100D3:
dec dword [ebp+.arg_8]
jns .loc_1008B
test esi, esi
jz @f
sub dword [ebp+.arg_0], 4
@@:
test edi, edi
jz @f
push dword [ebp+.arg_0]
call @$bdla$qpv
pop ecx
jmp .ret
@@:
mov eax, [ebp+.arg_0]
jmp .reteax
.ret:
xor eax, eax
.reteax:
pop edi
pop esi
pop ebx
mov esp, ebp
pop ebp
ret
enddef
;/**/

View File

@ -1,16 +0,0 @@
#ifndef __MENUET_LIB_H_INCLUDED_
#define __MENUET_LIB_H_INCLUDED_
// Menuet interface.
namespace Menuet // All menuet functions, types and data are nested in the (Menuet) namespace.
{
unsigned int StrLen(const char *str);
char *StrCopy(char *dest, const char *src);
void *MemCopy(void *dest, const void *src, unsigned int n);
void *MemSet(void *s, char c, unsigned int n);
double Floor(double x);
}
#endif // __MENUET_LIB_H_INCLUDED_

View File

@ -1,118 +0,0 @@
define @Menuet@StrLen$qpxc
push edi
cld
mov edi,[esp+8]
mov ecx,-1
xor al,al
repnz scas byte [edi]
not ecx
lea eax,[ecx-1]
pop edi
ret
enddef
define @Menuet@StrCopy$qpcpxc
push esi
push edi
cld
mov edi,[esp+16]
mov ecx,-1
mov esi,edi
xor al,al
repnz scas byte [edi]
not ecx
mov edi,[esp+12]
mov edx,ecx
mov eax,edi
shr ecx,2
rep movs dword [edi],[esi]
mov ecx,edx
and ecx,3
rep movs byte [edi],[esi]
pop edi
pop esi
ret
enddef
define @Menuet@MemCopy$qpvpxvui
push esi
push edi
cld
mov edi,[esp+12]
mov eax,edi
mov ecx,[esp+20]
mov esi,[esp+16]
mov edx,ecx
shr ecx,2
rep movs dword [edi],[esi]
mov ecx,edx
and ecx,3
rep movs byte [edi],[esi]
pop edi
pop esi
ret
enddef
define @Menuet@MemSet$qpvcui
push edi
cld
mov edi,[esp+8]
mov al,[esp+12]
mov ah,al
mov dx,ax
shl eax,16
mov ax,dx
mov ecx,[esp+16]
mov edx,ecx
shr ecx,2
rep stos dword [edi]
mov ecx,edx
and ecx,3
rep stos byte [edi]
pop edi
mov eax,[esp+4]
ret
enddef
define __ftol
sub esp,12
wait
fstcw word [esp+8]
wait
mov al,[esp+9]
or byte [esp+9],0x0c
fldcw word [esp+8]
fistp qword [esp]
mov [esp+9],al
fldcw word [esp+8]
mov eax,[esp]
mov edx,[esp+4]
add esp,12
ret
enddef
define @Menuet@Floor$qd
fld qword [esp+4]
mov ax,[esp+10]
shl ax,1
cmp ax,0x8680
ja Menuet_floor_end
mov ch,4
sub esp,2
wait
fstcw word [esp]
mov ax,0xf3ff
wait
mov dx,[esp]
and ax,dx
or ah,ch
mov [esp],ax
fldcw word [esp]
frndint
mov [esp],dx
fldcw word [esp]
add esp,2
Menuet_floor_end:
ret
enddef

View File

@ -1,90 +0,0 @@
use32
org 0x0
db 'MENUET01'
dd 0x1
dd MenuetEntryPoint
dd I_END
dd U_END+STACKSIZE+HEAPSIZE
dd U_END+STACKSIZE
dd 0x0,0x0
ptr equ
offset equ
short equ
tbyte equ tword
PTR equ
OFFSET equ
SHORT equ
TBYTE equ TWORD
macro movsb a,b
{
if a eq & b eq
movsb
else
movsx a,b
end if
}
macro movsw a,b
{
if a eq & b eq
movsw
else
movsx a,b
end if
}
macro segment name {}
macro endseg name {}
macro usedef [link]
{
common
if ~link eq
virtual at 0
forward
dd link
common
end virtual
end if
}
macro define x,[link]
{
common
if x eq
else if used x
x:
usedef link
}
macro enddef [link]
{
common
usedef link
end if
}
macro newdef x,[link]
{
common
end if
if x eq
else if used x
x:
usedef link
}
macro nextdef x,[link]
{
common
usedef x
end if
if x eq
else if used x
x:
usedef link
}

View File

@ -1,626 +0,0 @@
#ifndef __MEMORY_HEAP_RBTREE_H_INCLUDED_
#define __MEMORY_HEAP_RBTREE_H_INCLUDED_
namespace MemoryHeap
{
typedef unsigned int TMemItem;
enum {NumTreeSmall = 8 * sizeof(TMemItem)};
// Memory heap interface.
struct TFreeSpace
{
TMemItem Small[NumTreeSmall], Min, SmallMask;
};
struct TMemBlock
{
TMemItem *Begin;
};
bool BlockValid(const TMemBlock &block); // Is the given memory block valid?
void *BlockBegin(const TMemBlock &block); // Return the beginning address of the block.
void *BlockEnd(const TMemBlock &block); // Return the ending address of the block.
TFreeSpace &BlockFreeSpace(const TMemBlock &block); // Return the free space of the block.
void InitFreeSpace(TFreeSpace &fs); // Initialize the free space.
TMemBlock NullBlock(); // Return null invalid block.
TMemBlock CreateBlock(void *begin, void *end, TFreeSpace &fs);
// Create a memory block with the given begin and end and add free space of it to (fs),
//_ give (BlockAddSize) bytes of the block for it's data.
//_ (Program can alloc (end - begin - BlockAddSize) bytes after it,
//_ that must be not less than (MemMinSize) ).
TMemBlock CreateBlock(void *begin, void *end);
// Create a memory block with the given begin and end and new free space for it,
//_ give (BlockAddSizeFS) bytes of the block for it's data.
//_ (Program can alloc (end - begin - BlockAddSizeFS) bytes after it,
//_ that must be not less than (MemMinSize) ).
void ResizeBlock(TMemBlock block, void *new_end); // Resize the memory block to the given new end.
void RemoveBlock(TMemBlock block); // Remove the given memory block.
void *BlockEndFor(TMemBlock block, unsigned int size);
// Return the new end of the block needed for (ResizeBlock) to alloc the given size of memory.
unsigned int BlockSize(TMemBlock block); // Return the size of the given block.
unsigned int MemSize(void *mem); // Return the size of the allocced memory.
void *Alloc(TFreeSpace &fs, unsigned int size);
// Alloc a memory in the given free space, give (MemAddSize) bytes for it's data.
void *ReAlloc(TFreeSpace &fs, unsigned int size, void *mem);
// ReAlloc the given memory, it must lie in the block with the given free space.
void Free(TFreeSpace &fs, void *mem);
// Free the given memory, it must lie in the block with the given free space.
// Macro definitions.
#define MEMORY_HEAP_ALIGN_DOWN(s) (MemoryHeap::TMemItem(s) & ~(MemoryHeap::MemAlign - 1))
#define MEMORY_HEAP_ALIGN_UP(s) ((MemoryHeap::TMemItem(s) + (MemoryHeap::MemAlign - 1)) & ~(MemoryHeap::MemAlign - 1))
#define MEMORY_HEAP_ITEM(s,k) ( ((MemoryHeap::TMemItem*)(s))[(k)] )
#define MEMORY_HEAP_NEXT(s) (MEMORY_HEAP_ITEM((s),-1))
#define MEMORY_HEAP_PREV(s) (MEMORY_HEAP_ITEM((s),-2))
#define MEMORY_HEAP_FREE(s) (MEMORY_HEAP_ITEM((s),-1) & 1)
// Constants.
enum {MemAlign = sizeof(TMemItem)};
enum {MemAddSize = MEMORY_HEAP_ALIGN_UP(2 * sizeof(TMemItem))};
enum {BlockEndSize = MemAddSize};
enum {BlockAddSize = MEMORY_HEAP_ALIGN_UP(4 * sizeof(TMemItem)) + BlockEndSize};
enum {BlockAddSizeFS = BlockAddSize + BlockEndSize + MEMORY_HEAP_ALIGN_UP(sizeof(TFreeSpace))};
enum {MemMinSize = MEMORY_HEAP_ALIGN_UP(2 * sizeof(TMemItem))};
// Inline functions.
inline bool BlockValid(const TMemBlock &block) {return block.Begin != 0;}
inline void *BlockBegin(const TMemBlock &block) {return (void*)block.Begin;}
inline void *BlockEnd(const TMemBlock &block) {return block.Begin ? (void*)block.Begin[1] : 0;}
inline TFreeSpace &BlockFreeSpace(const TMemBlock &block) {return *(TFreeSpace*)block.Begin[0];}
inline TMemBlock NullBlock() {TMemBlock block; block.Begin = 0; return block;}
inline void *BlockEndFor(TMemBlock block, unsigned int size)
{
TMemItem last = (TMemItem)block.Begin[1];
TMemItem prevlast = MEMORY_HEAP_PREV(last);
return (void*)( (MEMORY_HEAP_FREE(prevlast) ? prevlast : last) + MemAddSize +
((size <= MemMinSize) ? MemMinSize : MEMORY_HEAP_ALIGN_UP(size)) );
}
inline unsigned int BlockSize(TMemBlock block)
{
if (!block.Begin) return 0;
return (unsigned int)(block.Begin[1] - (TMemItem)block.Begin);
}
inline unsigned int MemSize(void *mem)
{
if (!mem) return 0;
TMemItem c = (TMemItem)mem;
return MEMORY_HEAP_NEXT(c) - c - MemAddSize;
}
// Free space item functions.
TMemItem _FirstNotZeroBit(TMemItem i)
{
TMemItem r = 0;
while ((i >>= 1) != 0) r++;
return r;
}
void _RBTreeRotate(TMemItem parent, TMemItem item, int side)
{
TMemItem temp = MEMORY_HEAP_ITEM(parent,0);
MEMORY_HEAP_ITEM(item,0) = temp;
if (temp)
{
if (MEMORY_HEAP_ITEM(temp,2) == parent)
{
MEMORY_HEAP_ITEM(temp,2) = item;
}
else MEMORY_HEAP_ITEM(temp,3) = item;
}
temp = MEMORY_HEAP_ITEM(item,side^1);
if (temp) MEMORY_HEAP_ITEM(temp,0) = parent;
MEMORY_HEAP_ITEM(parent,side) = temp;
MEMORY_HEAP_ITEM(parent,0) = item;
MEMORY_HEAP_ITEM(item,side^1) = parent;
temp = MEMORY_HEAP_ITEM(parent,1);
MEMORY_HEAP_ITEM(parent,1) = MEMORY_HEAP_ITEM(item,1);
MEMORY_HEAP_ITEM(item,1) = temp;
}
void InitFreeSpace(TFreeSpace &fs)
{
TMemItem i;
for (i = 0; i <= NumTreeSmall; i++) fs.Small[i] = 0;
fs.Min = 0; fs.SmallMask = 0;
}
void _FreeAdd(TFreeSpace &fs, TMemItem item)
{
TMemItem size = MEMORY_HEAP_NEXT(item) - item;
if (size < MemAddSize + MemMinSize + MemAlign * NumTreeSmall)
{
TMemItem s = (size - (MemAddSize + MemMinSize)) / MemAlign;
TMemItem &addto = fs.Small[s];
MEMORY_HEAP_ITEM(item,1) = (TMemItem)(&addto);
MEMORY_HEAP_ITEM(item,0) = (TMemItem)addto;
if (addto) MEMORY_HEAP_ITEM(addto,1) = item;
addto = item;
fs.SmallMask |= TMemItem(1) << s;
return;
}
TMemItem addto = fs.Min, parent, temp;
MEMORY_HEAP_ITEM(item,2) = 0;
MEMORY_HEAP_ITEM(item,3) = 0;
if (!addto)
{
MEMORY_HEAP_ITEM(item,0) = 0;
MEMORY_HEAP_ITEM(item,1) = 1;
fs.Min = item;
return;
}
MEMORY_HEAP_ITEM(item,1) = 0;
TMemItem side = 2;
if (MEMORY_HEAP_NEXT(addto) - addto >= size) fs.Min = item;
else
{
for (;;)
{
parent = MEMORY_HEAP_ITEM(addto,0);
if (!parent) break;
if (MEMORY_HEAP_NEXT(parent) - parent < size) addto = parent;
else break;
}
for (;;)
{
if (MEMORY_HEAP_NEXT(addto) - addto < size)
{
temp = MEMORY_HEAP_ITEM(addto,3);
if (!temp) {side = 3; break;}
addto = temp;
}
else
{
temp = MEMORY_HEAP_ITEM(addto,2);
if (!temp) break;
addto = temp;
}
}
}
MEMORY_HEAP_ITEM(item,0) = addto;
MEMORY_HEAP_ITEM(addto,side) = item;
for (;;)
{
if (MEMORY_HEAP_ITEM(addto,1) != 0) return;
parent = MEMORY_HEAP_ITEM(addto,0);
temp = MEMORY_HEAP_ITEM(parent,2);
if (temp == addto)
{
temp = MEMORY_HEAP_ITEM(parent,3);
side = 2;
}
else side = 3;
if (!temp || MEMORY_HEAP_ITEM(temp,1) != 0) break;
MEMORY_HEAP_ITEM(addto,1) = 1;
MEMORY_HEAP_ITEM(temp,1) = 1;
item = parent;
addto = MEMORY_HEAP_ITEM(item,0);
if (!addto) return;
MEMORY_HEAP_ITEM(item,1) = 0;
}
if (MEMORY_HEAP_ITEM(addto,side) != item)
{
temp = MEMORY_HEAP_ITEM(item,side);
if (temp) MEMORY_HEAP_ITEM(temp,0) = addto;
MEMORY_HEAP_ITEM(addto,side^1) = temp;
MEMORY_HEAP_ITEM(addto,0) = item;
MEMORY_HEAP_ITEM(item,side) = addto;
MEMORY_HEAP_ITEM(item,0) = parent;
MEMORY_HEAP_ITEM(parent,side) = item;
}
else item = addto;
_RBTreeRotate(parent, item, side);
}
void _FreeDel(TFreeSpace &fs, TMemItem item)
{
TMemItem size = MEMORY_HEAP_NEXT(item) - item;
if (size < MemAddSize + MemMinSize + MemAlign * NumTreeSmall)
{
TMemItem prev = MEMORY_HEAP_ITEM(item,1);
TMemItem next = MEMORY_HEAP_ITEM(item,0);
MEMORY_HEAP_ITEM(prev,0) = next;
if (next) MEMORY_HEAP_ITEM(next,1) = prev;
else
{
TMemItem s = (size - (MemAddSize + MemMinSize)) / MemAlign;
if (!fs.Small[s]) fs.SmallMask &= ~(TMemItem(1) << s);
}
return;
}
TMemItem parent, temp, second, add;
TMemItem side = 2;
temp = MEMORY_HEAP_ITEM(item,3);
if (temp)
{
for (;;)
{
second = temp;
temp = MEMORY_HEAP_ITEM(temp,2);
if (!temp) break;
}
if (fs.Min == item) fs.Min = second;
add = MEMORY_HEAP_ITEM(second,3);
parent = MEMORY_HEAP_ITEM(second,0);
if (parent == item) {parent = second; side = 3;}
else
{
temp = MEMORY_HEAP_ITEM(item,3);
MEMORY_HEAP_ITEM(second,3) = temp;
MEMORY_HEAP_ITEM(temp,0) = second;
}
temp = MEMORY_HEAP_ITEM(item,2);
MEMORY_HEAP_ITEM(second,2) = temp;
if (temp) MEMORY_HEAP_ITEM(temp,0) = second;
temp = MEMORY_HEAP_ITEM(item,0);
MEMORY_HEAP_ITEM(second,0) = temp;
if (temp)
{
if (MEMORY_HEAP_ITEM(temp,2) == item)
{
MEMORY_HEAP_ITEM(temp,2) = second;
}
else MEMORY_HEAP_ITEM(temp,3) = second;
}
MEMORY_HEAP_ITEM(parent,side) = add;
if (add) MEMORY_HEAP_ITEM(add,0) = parent;
bool color = MEMORY_HEAP_ITEM(second,1);
MEMORY_HEAP_ITEM(second,1) = MEMORY_HEAP_ITEM(item,1);
if (!color) return;
}
else
{
if (fs.Min == item) fs.Min = MEMORY_HEAP_ITEM(item,0);
add = MEMORY_HEAP_ITEM(item,2);
parent = MEMORY_HEAP_ITEM(item,0);
if (add) MEMORY_HEAP_ITEM(add,0) = parent;
if (parent)
{
if (MEMORY_HEAP_ITEM(parent,2) == item)
{
MEMORY_HEAP_ITEM(parent,2) = add;
}
else
{
MEMORY_HEAP_ITEM(parent,3) = add;
side = 3;
}
}
else
{
if (add) MEMORY_HEAP_ITEM(add,1) = 1;
return;
}
if (!MEMORY_HEAP_ITEM(item,1)) return;
}
if (add && !MEMORY_HEAP_ITEM(add,1))
{
MEMORY_HEAP_ITEM(add,1) = 1;
return;
}
for (;;)
{
second = MEMORY_HEAP_ITEM(parent,side^1);
if (!MEMORY_HEAP_ITEM(second,1))
{
_RBTreeRotate(parent, second, side^1);
second = MEMORY_HEAP_ITEM(parent,side^1);
}
temp = MEMORY_HEAP_ITEM(second,side^1);
if (temp && !MEMORY_HEAP_ITEM(temp,1))
{
MEMORY_HEAP_ITEM(temp,1) = 1;
break;
}
temp = MEMORY_HEAP_ITEM(second,side);
if (temp && !MEMORY_HEAP_ITEM(temp,1))
{
_RBTreeRotate(second, temp, side);
MEMORY_HEAP_ITEM(second,1) = 1;
second = temp;
break;
}
MEMORY_HEAP_ITEM(second,1) = 0;
if (!MEMORY_HEAP_ITEM(parent,1))
{
MEMORY_HEAP_ITEM(parent,1) = 1;
return;
}
second = parent;
parent = MEMORY_HEAP_ITEM(second,0);
if (!parent) return;
if (MEMORY_HEAP_ITEM(parent,2) == second) side = 2;
else side = 3;
}
_RBTreeRotate(parent, second, side^1);
}
TMemItem _FreeFindAfter(TMemItem item, TMemItem size)
{
if (!item) return 0;
TMemItem paritem, s;
if (MEMORY_HEAP_NEXT(item) - item >= size) return item;
for (;;)
{
paritem = MEMORY_HEAP_ITEM(item,0);
if (!paritem) break;
s = MEMORY_HEAP_NEXT(paritem) - paritem;
if (s == size) return paritem;
if (s < size) item = paritem;
else break;
}
MEMORY_HEAP_ITEM(item,3);
for (;;)
{
if (!item) return paritem;
s = MEMORY_HEAP_NEXT(item) - item;
if (s == size) return item;
if (s < size) item = MEMORY_HEAP_ITEM(item,3);
else
{
paritem = item;
item = MEMORY_HEAP_ITEM(item,2);
}
}
}
TMemItem _FreeFind(TFreeSpace &fs, TMemItem size)
{
TMemItem item, nextitem, s;
if (size < MemAddSize + MemMinSize + MemAlign * NumTreeSmall)
{
TMemItem m, t;
s = (size - (MemAddSize + MemMinSize)) / MemAlign;
item = fs.Small[s];
if (item) return item;
if (size < MemAlign * NumTreeSmall)
{
t = size / MemAlign;
m = fs.SmallMask >> t;
if (m) return fs.Small[t + _FirstNotZeroBit(m)];
else if (fs.Min) return fs.Min;
}
else
{
item = _FreeFindAfter(fs.Min, size + 1 + MemAddSize + MemMinSize);
if (item) return item;
}
m = fs.SmallMask >> s;
if (m) return fs.Small[s + _FirstNotZeroBit(m)];
else return fs.Min;
}
item = _FreeFindAfter(fs.Min, ++size);
if (!item) return 0;
s = MEMORY_HEAP_NEXT(item) - item;
if (s == size) return item;
size += MemAddSize + MemMinSize;
if (s >= size) return item;
nextitem = _FreeFindAfter(item, size);
return nextitem ? nextitem : item;
}
// Block functions.
inline void _CreateBlockEnd(TMemBlock &block, TFreeSpace &fs, TMemItem c, TMemItem e)
{
block.Begin[0] = (TMemItem)(&fs);
if (e - c < TMemItem(MemAddSize + MemMinSize))
{
MEMORY_HEAP_NEXT(c) = 0;
block.Begin[1] = c;
}
else
{
MEMORY_HEAP_NEXT(c) = e + 1;
_FreeAdd(fs, c);
MEMORY_HEAP_PREV(e) = c;
MEMORY_HEAP_NEXT(e) = 0;
block.Begin[1] = e;
}
}
TMemBlock CreateBlock(void *begin, void *end, TFreeSpace &fs)
{
TMemBlock block = {0};
TMemItem b = MEMORY_HEAP_ALIGN_UP(begin);
TMemItem e = MEMORY_HEAP_ALIGN_DOWN(end);
if (e <= b || e - b < TMemItem(BlockAddSize - MemAddSize)) return block;
block.Begin = (TMemItem*)b;
b += MEMORY_HEAP_ALIGN_UP(4 * sizeof(TMemItem));
MEMORY_HEAP_PREV(b) = 0;
_CreateBlockEnd(block, fs, b, e);
return block;
}
TMemBlock CreateBlock(void *begin, void *end)
{
TMemBlock block = {0};
TMemItem b = MEMORY_HEAP_ALIGN_UP(begin);
TMemItem e = MEMORY_HEAP_ALIGN_DOWN(end);
if (e <= b || e - b < TMemItem(BlockAddSizeFS - MemAddSize)) return block;
block.Begin = (TMemItem*)b;
b += MEMORY_HEAP_ALIGN_UP(4 * sizeof(TMemItem));
TMemItem c = b + MemAddSize + MEMORY_HEAP_ALIGN_UP(sizeof(TFreeSpace));
MEMORY_HEAP_PREV(b) = 0;
MEMORY_HEAP_NEXT(b) = c;
MEMORY_HEAP_PREV(c) = b;
InitFreeSpace(*(TFreeSpace*)b);
_CreateBlockEnd(block, *(TFreeSpace*)b, c, e);
return block;
}
void ResizeBlock(TMemBlock block, void *new_end)
{
if (!BlockValid(block)) return;
TMemItem e = MEMORY_HEAP_ALIGN_DOWN(new_end);
TMemItem c = block.Begin[1];
TFreeSpace &fs = *(TFreeSpace*)block.Begin[0];
do
{
if (c == e) return;
else if (c > e)
{
while ((c = MEMORY_HEAP_PREV(c)) > e)
{
if (MEMORY_HEAP_FREE(c)) _FreeDel(fs, c);
}
if (!c) {block.Begin = 0; return;}
if (MEMORY_HEAP_FREE(c))
{
_FreeDel(fs, c);
if (e - c < TMemItem(MemAddSize + MemMinSize)) e = c;
else
{
MEMORY_HEAP_NEXT(c) = e + 1;
_FreeAdd(*(TFreeSpace*)block.Begin[0], c);
break;
}
}
else if (e - c >= TMemItem(MemAddSize + MemMinSize))
{
MEMORY_HEAP_NEXT(c) = e; break;
}
MEMORY_HEAP_NEXT(c) = 0;
block.Begin[1] = c;
if (c == e) return;
}
TMemItem pc = MEMORY_HEAP_PREV(c);
if (pc && MEMORY_HEAP_FREE(pc)) _FreeDel(fs, c = pc);
else if (e - c < TMemItem(MemAddSize + MemMinSize)) return;
MEMORY_HEAP_NEXT(c) = e + 1;
_FreeAdd(fs, c);
} while(false);
MEMORY_HEAP_PREV(e) = c;
MEMORY_HEAP_NEXT(e) = 0;
block.Begin[1] = e;
}
void RemoveBlock(TMemBlock block)
{
if (!BlockValid(block)) return;
TMemItem e = block.Begin[1];
TFreeSpace &fs = *(TFreeSpace*)block.Begin[0];
while ((e = MEMORY_HEAP_PREV(e)) != 0)
{
if (MEMORY_HEAP_FREE(e)) _FreeDel(fs, e);
}
block.Begin = 0;
}
// Free space functions.
void _CopyMemItemArray(TMemItem dest, TMemItem src, TMemItem end)
{
TMemItem k = (end - src) / sizeof(TMemItem);
TMemItem *d = (TMemItem*)dest;
TMemItem *s = (TMemItem*)src;
while (k--) *(d++) = *(s++);
}
void *Alloc(TFreeSpace &fs, unsigned int size)
{
if (!size) return 0;
TMemItem s = MEMORY_HEAP_ALIGN_UP(size) + MemAddSize;
if (s < MemAddSize + MemMinSize) s = MemAddSize + MemMinSize;
TMemItem c = _FreeFind(fs, s);
if (!c) return 0;
_FreeDel(fs, c);
TMemItem nc = --MEMORY_HEAP_NEXT(c);
TMemItem mc = c + s;
if (nc - (MemAddSize + MemMinSize) >= mc)
{
MEMORY_HEAP_NEXT(c) = mc;
MEMORY_HEAP_PREV(mc) = c;
MEMORY_HEAP_NEXT(mc) = nc + 1;
MEMORY_HEAP_PREV(nc) = mc;
_FreeAdd(fs, mc);
}
return (void*)c;
}
void *ReAlloc(TFreeSpace &fs, void *mem, unsigned int size)
{
if (!mem) return Alloc(fs, size);
if (!size) {Free(fs, mem); return 0;}
TMemItem s = MEMORY_HEAP_ALIGN_UP(size) + MemAddSize;
TMemItem c = (TMemItem)mem;
TMemItem mc = MEMORY_HEAP_NEXT(c);
TMemItem nc = MEMORY_HEAP_NEXT(mc);
if (--nc & 1) nc = mc;
if (s < MemAddSize + MemMinSize) s = MemAddSize + MemMinSize;
if (nc - c < s)
{
mem = Alloc(fs, size);
if (mem)
{
_CopyMemItemArray((TMemItem)mem, c, mc - MemAddSize);
Free(fs, (void*)c);
return mem;
}
else
{
TMemItem pc = MEMORY_HEAP_PREV(c);
if (pc && MEMORY_HEAP_FREE(pc) && nc - pc >= s)
{
_FreeDel(fs, pc);
_CopyMemItemArray(pc, c, mc - MemAddSize);
c = pc;
}
else return 0;
}
}
if (mc < nc) _FreeDel(fs, mc);
mc = c + s;
if (nc - (MemAddSize + MemMinSize) >= mc)
{
MEMORY_HEAP_NEXT(c) = mc;
MEMORY_HEAP_PREV(mc) = c;
MEMORY_HEAP_NEXT(mc) = nc + 1;
MEMORY_HEAP_PREV(nc) = mc;
_FreeAdd(fs, mc);
}
else
{
MEMORY_HEAP_NEXT(c) = nc;
MEMORY_HEAP_PREV(nc) = c;
}
return (void*)c;
}
int free_a = 0;
void Free(TFreeSpace &fs, void *mem)
{
TMemItem c = (TMemItem)mem;
if (!c) return;
TMemItem pc = MEMORY_HEAP_PREV(c);
TMemItem mc = MEMORY_HEAP_NEXT(c);
TMemItem nc = MEMORY_HEAP_NEXT(mc);
if (--nc & 1) nc = mc;
else _FreeDel(fs, mc);
if (free_a == 1) return;
if (pc && MEMORY_HEAP_FREE(pc)) _FreeDel(fs, c = pc);
MEMORY_HEAP_NEXT(c) = nc + 1;
MEMORY_HEAP_PREV(nc) = c;
if (free_a == 2) return;
_FreeAdd(fs, c);
}
}
#endif // ndef __MEMORY_HEAP_RBTREE_H_INCLUDED_

View File

@ -1,536 +0,0 @@
#ifndef __MENUET_H_INCLUDED_
#define __MENUET_H_INCLUDED_
#include <me_lib.h>
// Menuet interface.
namespace Menuet // All menuet functions, types and data are nested in the (Menuet) namespace.
{
const char *DebugPrefix = "User program: ";
struct TWindowData // Data for drawing a window.
{
unsigned short WindowType, HeaderType;
unsigned long WindowColor, HeaderColor, BorderColor, TitleColor;
const char *Title;
};
struct TStartData // This structure is used only for MenuetOnStart function.
{
unsigned short Left, Width, Top, Height; // Initial window rectangle.
TWindowData WinData;
};
typedef void **TThreadData; // Thread data are the fast identifier of thread, contains user dword in
//_ the zero element and stack beginning (or zero if it is unknown) in the first element.
//_ The stack will be deleted from dynamic memory at the finish of the thread if stack beginning is not zero.
struct TMutex; // Simple mutex can be locked only once at a time.
#define MENUET_MUTEX_INIT {} // Simple mutex initializer, cat be redefined in a realization of the library
struct TRecMutex; // Recursive mutex can be locked many times by a single thread at a time.
#define MENUET_REC_MUTEX_INIT {} // Recursive mutex initializer, cat be redefined in a realization of the library
// Some functions have two forms: the fast form with (thread_data) parameter and the form without it.
// Note: pass only thread data of current thread as (thread_data) parameter to these functions.
void Main(); // Main function is called at program startup.
void* ThreadMain(void *user = 0, void *stack_begin = 0);
// Called at thread startup, (user) is placed in thread data as a user dword,
//_ (stack_begin) is placed in thread data as a stack beginning.
//_ Return new value of stack beginning that can be changed in the thread data.
void GetWindowData(TWindowData &win_data); // Write current window data to (win_data).
void GetWindowData(TWindowData &win_data, TThreadData thread_data);
void SetWindowData(const TWindowData &win_data); // Replace current window data by (win_data).
void SetWindowData(const TWindowData &win_data, TThreadData thread_data);
void CloseWindow(); // Close current window when returning to message loop.
void CloseWindow(TThreadData thread_data);
void Redraw(int frame = 0); // Redraw current window immediately, if (frame) is positive redraw the frame too,
void Redraw(int frame, TThreadData thread_data); //_ if (frame) is negative redraw only invalideted window.
void Invalidate(int frame = 0); // Redraw current window when no message will be is the queue,
void Invalidate(int frame, TThreadData thread_data); //_ if (frame) is positive redraw the frame too,
//_ if (frame) is negative do nothing.
void MoveWindow(const int window_rect[/* 4 */]); // Move and resize current window.
void Abort(); // Abnormally terminate a program.
void ExitProcess(); // Exit from the process, don't call any destructors of global varyables
void ExitThread(); // Exit from the current thread
void ExitThread(TThreadData thread_data);
void ReturnMessageLoop(); // Return to the message loop of the thread. Exit from the thread
void ReturnMessageLoop(TThreadData thread_data); //_ if it is called from (MenuetOnStart).
void Delay(unsigned int time); // Delay the execution of the program during (time) hundredth seconds.
unsigned int Clock(); // Return the time from starting of the system to this moment in hundredth of seconds.
int GetPackedTime(); // Return the current time of day in binary-decimal format 0x00SSMMHH.
void GetTime(int t[/* 3 */]); // Write the current time to (t): t[0] = second, t[1] = minute, t[2] = hour.
int GetPackedDate(); // Return the current date in binary-decimal format 0x00YYDDMM.
void GetDate(int d[/* 3 */]); // Write the current date to (d): d[0] = day, d[1] = month, d[2] = year.
void GetTimeDate(int t[/* 6 */]); // Write the current time and date to (t): t[0] = second,
//_ t[1] = minute, t[2] = hour, t[3] = day, t[4] = month, t[5] = year.
void ReadCommonColors(unsigned int colors[/* 10 */]); // Writes standart window colors to (colors).
unsigned int GetProcessInfo(unsigned int *use_cpu, char process_name[/* 13 */], unsigned int *use_memory,
unsigned int *pid, int window_rect[/* 4 */], unsigned int pid_for = -1);
// Write (pid_for) process information to variables parameters points, return
//_ the number of processes. (pid_for) equal to (-1) means current process.
unsigned int GetPid(); // Return the current thread identifier (pid).
unsigned int GetPid(TThreadData thread_data);
TThreadData GetThreadData(); // Return the thread data of the current thread.
TThreadData GetThreadData(unsigned int pid); // Return the thread data of the thread with the given pid.
void* GetPicture(unsigned short &width, unsigned short &height);
void* GetPicture(unsigned short &width, unsigned short &height, TThreadData thread_data);
// Return the picture on the window and write its width and height to (width) and (height).
void SetPicture(void *picture, unsigned short width, unsigned short height);
void SetPicture(void *picture, unsigned short width, unsigned short height, TThreadData thread_data);
// Replace the picture on the window by the given picture with the given width and height.
void GetBorderHeader(unsigned short &border_size, unsigned short &header_size);
void GetBorderHeader(unsigned short &border_size, unsigned short &header_size, TThreadData thread_data);
// Write the border thickness to (border_size) and header height to (header_size).
void GetClientSize(unsigned short &width, unsigned short &height);
void GetClientSize(unsigned short &width, unsigned short &height, TThreadData thread_data);
// Write the client area width and height to (width) and (height) parameters.
void GetClientSize(unsigned short &width, unsigned short &height, int win_width, int win_height);
void GetClientSize(unsigned short &width, unsigned short &height, int win_width, int win_height, TThreadData thread_data);
// Write the client area size of window with the width (win_width)
//_ and height (win_height) to (width) and (height) parameters.
void GetScreenSize(unsigned short &width, unsigned short &height);
// Write the screen width and height to (width) and (height) parameters.
void InitMutex(TMutex *mutex); // Initialize the simple mutex.
void InitRecMutex(TRecMutex *mutex); // Initialize the recursive mutex.
bool TryLock(TMutex *mutex); // Try to lock the mutex without waitting, return true if lock.
bool TryLock(TRecMutex *mutex);
bool TryLock(TRecMutex *mutex, TThreadData thread_data);
bool TryLock(TRecMutex *mutex, unsigned int pid);
void Lock(TMutex *mutex); // Lock mutex and wait for it if this necessary.
void Lock(TRecMutex *mutex);
void Lock(TRecMutex *mutex, TThreadData thread_data);
void Lock(TRecMutex *mutex, unsigned int pid);
bool LockTime(TMutex *mutex, int time);
bool LockTime(TRecMutex *mutex, int time); // Lock mutex and wait for it during (time) hundredth seconds.
bool LockTime(TRecMutex *mutex, int time, TThreadData thread_data);
bool LockTime(TRecMutex *mutex, int time, unsigned int pid);
void UnLock(TMutex *mutex); // Unlock mutex
void UnLock(TRecMutex *mutex);
void UnLock(TRecMutex *mutex, TThreadData thread_data);
void UnLock(TRecMutex *mutex, unsigned int pid);
void DebugPutChar(char c); // Put the character to the debug board.
void DebugPutString(const char *s); // Put the string to the debug board.
int GetKey(); // Return key pressed by user or -1 if no key was pressed.
int GetMouseButton(); // Return buttons pressed: 0 - no buttons, 1 - left button, 2 - right button, 3 - both buttons.
void GetMousePosition(short &x, short &y, bool absolute = false);
// Write mouse position to (x) and (y): absolute if (absolute) is true and relative the window otherwise.
void GetMousePosPicture(short &x, short &y);
int GetThreadNumber(); // Return the number of threads currently executing.
bool WasThreadCreated(); // Return true if there was created at least one thread except the main thred.
unsigned int CreateThread(void *user = 0, unsigned int stack_size = 0, void *stack_end = 0);
// Create a new thread with the user dword (user) and stack pointer (stack_end).
//_ If (stack_end) is zero, create stack in dynamic memory of size (stack_size) or
//_ the same size as the main thread if (stack_size) less that 4096. Set the beginning
//_ of the stack if (stack_end) is zero or (stack_size) is not zero, in this case stack
//_ will be deleted automaticaly from dynamic memory at the finish of the thread.
}
// Function, defined outside.
bool MenuetOnStart(Menuet::TStartData &me_start, Menuet::TThreadData thread_data);
// Window will be created iff return value is true.
bool MenuetOnClose(Menuet::TThreadData thread_data); // Window will be closed iff return value is true.
int MenuetOnIdle(Menuet::TThreadData thread_data); // Return the time to wait next message.
void MenuetOnSize(int window_rect[/* 4 */], Menuet::TThreadData thread_data); // When the window is resized.
void MenuetOnKeyPress(Menuet::TThreadData thread_data); // When user press a key.
void MenuetOnMouse(Menuet::TThreadData thread_data); // When user move a mouse.
#ifdef __MENUET__
namespace Menuet
{
// Structures.
struct TMutex // Simple mutex can be locked only once at a time.
{
unsigned int mut;
};
#undef MENUET_MUTEX_INIT
#define MENUET_MUTEX_INIT {0x40} // Simple mutex initializer, cat be redefined in a realization of the library
struct TRecMutex // Recursive mutex can be locked many times by a single thread at a time.
{
unsigned int mut, pid;
};
#undef MENUET_REC_MUTEX_INIT
#define MENUET_REC_MUTEX_INIT {0x20,-1} // Recursive mutex initializer, cat be redefined in a realization of the library
// Global variables.
volatile TThreadData _ThreadTable[256];
volatile unsigned int _ThreadScanCount[2] = {0, 0};
volatile int _ThreadNumber = 1;
volatile int _ExitProcessNow = 0;
TMutex _ThreadMutex = MENUET_MUTEX_INIT;
unsigned int _ThreadSavedBegProc[4];
// Inline functions.
inline void GetWindowData(TWindowData &win_data) {GetWindowData(win_data, GetThreadData());}
inline void SetWindowData(const TWindowData &win_data) {SetWindowData(win_data, GetThreadData());}
inline void CloseWindow() {CloseWindow(GetThreadData());}
inline void Redraw(int frame) {Redraw(frame, GetThreadData());}
inline void Invalidate(int frame) {Invalidate(frame, GetThreadData());}
inline void* GetPicture(unsigned short &width, unsigned short &height)
{
return GetPicture(width, height, GetThreadData());
}
inline void SetPicture(void *picture, unsigned short width, unsigned short height)
{
SetPicture(picture, width, height, GetThreadData());
}
inline void GetBorderHeader(unsigned short &border_size, unsigned short &header_size)
{
GetBorderHeader(border_size, header_size, GetThreadData());
}
inline void GetClientSize(unsigned short &width, unsigned short &height)
{
unsigned int pid;
int rect[4];
GetProcessInfo(0, 0, 0, &pid, rect);
GetClientSize(width, height, rect[2], rect[3], GetThreadData(pid));
}
inline void GetClientSize(unsigned short &width, unsigned short &height, TThreadData thread_data)
{
int rect[4];
GetProcessInfo(0, 0, 0, 0, rect);
GetClientSize(width, height, rect[2], rect[3], thread_data);
}
inline void GetClientSize(unsigned short &width, unsigned short &height, int win_width, int win_height)
{
GetClientSize(width, height, win_width, win_height, GetThreadData());
}
inline void GetTimeDate(int t[/* 6 */]) {GetTime(t); GetDate(t + 3);}
inline void InitMutex(TMutex *mutex) {mutex->mut = 0;}
inline void InitRecMutex(TRecMutex *mutex) {mutex->mut = 0; mutex->pid = -1;}
inline bool TryLock(TRecMutex *mutex) {return TryLock(mutex, GetPid());}
inline bool TryLock(TRecMutex *mutex, TThreadData thread_data) {return TryLock(mutex, GetPid(thread_data));}
inline void Lock(TRecMutex *mutex) {Lock(mutex, GetPid());}
inline void Lock(TRecMutex *mutex, TThreadData thread_data) {Lock(mutex, GetPid(thread_data));}
inline bool LockTime(TRecMutex *mutex, int time) {return LockTime(mutex, time, GetPid());}
inline bool LockTime(TRecMutex *mutex, int time, TThreadData thread_data)
{return LockTime(mutex, time, GetPid(thread_data));}
inline void UnLock(TRecMutex *mutex) {UnLock(mutex, GetPid());}
inline void UnLock(TRecMutex *mutex, TThreadData thread_data) {UnLock(mutex, GetPid(thread_data));}
inline int GetThreadNumber() {return _ThreadNumber;}
// Constants from fasm.
#include <me_func.inc>
// Functions.
unsigned char _HashByte(unsigned int value);
unsigned short _HashWord(unsigned int value);
unsigned int _HashDword(unsigned int value);
void _GetStartData(TStartData &start_data, TThreadData thread_data)
{
start_data.Left = (unsigned short)((unsigned long)thread_data[MENUET_THREAD_DATA_X] >> 16);
start_data.Width = (unsigned short)((unsigned long)thread_data[MENUET_THREAD_DATA_X]);
start_data.Top = (unsigned short)((unsigned long)thread_data[MENUET_THREAD_DATA_Y] >> 16);
start_data.Height = (unsigned short)((unsigned long)thread_data[MENUET_THREAD_DATA_Y]);
GetWindowData(start_data.WinData, thread_data);
}
void _SetStartData(const TStartData &start_data, TThreadData thread_data)
{
(unsigned long&)thread_data[MENUET_THREAD_DATA_X] =
((unsigned int)start_data.Left << 16) | start_data.Width;
(unsigned long&)thread_data[MENUET_THREAD_DATA_Y] =
((unsigned int)start_data.Top << 16) | start_data.Height;
SetWindowData(start_data.WinData, thread_data);
}
void _ApplyCommonColors(TWindowData &win_data)
{
unsigned int colors[10];
ReadCommonColors(colors);
win_data.WindowColor = colors[5];
win_data.HeaderColor = colors[1];
win_data.BorderColor = colors[0];
win_data.TitleColor = colors[4];
}
void _SetValueFunctionPriority(void *beg, int n)
{
int k, i;
unsigned char num[256];
for (i = 0; i < 256; i++) num[i] = 0;
for (k = 0; k < n; k++)
{
i = ((unsigned char*)beg + 6*k)[1];
((unsigned char*)beg + 6*k)[0] = num[i];
if (num[i] != 255) num[i]++;
}
}
void _CallFunctionPriority(void *beg, void *end, bool reverse = false)
{
struct _Local
{
static int cmp(void *beg, int i, int j)
{
unsigned char *x = (unsigned char*)beg + 6*i;
unsigned char *y = (unsigned char*)beg + 6*j;
if (*(unsigned short*)x < *(unsigned short*)y) return -1;
if (*(unsigned short*)x > *(unsigned short*)y) return 1;
return 0;
}
static void swap(void *beg, int i, int j)
{
unsigned char *x = (unsigned char*)beg + 6*i;
unsigned char *y = (unsigned char*)beg + 6*j;
short s;
int t;
s = *(short*)x; *(short*)x = *(short*)y; *(short*)y = s;
x += 2; y += 2;
t = *(int*)x; *(int*)x = *(int*)y; *(int*)y = t;
}
static void call(void *beg, int i)
{
unsigned char *x = (unsigned char*)beg + 6*i;
(*(void(**)())(x+2))();
}
};
if (!beg || !end || end <= beg) return;
int i, j, k, m, n;
n = ((unsigned char*)end - (unsigned char*)beg) / 6;
if (n <= 0) return;
_SetValueFunctionPriority(beg, n);
m = n; k = n;
while (m > 1)
{
if (k > 0) k--;
else _Local::swap(beg, 0, --m);
j = k;
for (;;)
{
i = j;
if (2*i + 1 >= m) break;
if (_Local::cmp(beg, 2*i + 1, j) > 0) j = 2*i + 1;
if (2*i + 2 < m && _Local::cmp(beg, 2*i + 2, j) > 0) j = 2*i + 2;
if (i == j) break;
_Local::swap(beg, i, j);
}
}
if (!reverse)
{
for (k = 0; k < n; k++) _Local::call(beg, k);
}
else
{
for (k = n-1; k >= 0; k--) _Local::call(beg, k);
}
}
bool _CallStart(TThreadData thread_data, void *init = 0, void *init_end = 0)
{
struct _TThreadDataTemplate
{
unsigned int data[12];
};
static const _TThreadDataTemplate _ThreadDataTemplate =
{{3, 0x00320100, 0x00320100, 0x33FFFFFF, 0x806060FF, 0x00000000, 0x00FFFF40, 0, 0, 0, -1, -1}};
unsigned int pid = GetPid();
volatile TThreadData *thread_table_item;
Lock(&_ThreadMutex);
if (_ExitProcessNow) ExitProcess();
thread_table_item = &_ThreadTable[_HashByte(pid)];
thread_data[MENUET_THREAD_DATA_NEXT] = (void*)*thread_table_item;
(unsigned int&)thread_data[MENUET_THREAD_DATA_PID] = pid;
*(_TThreadDataTemplate*)(thread_data + MENUET_THREAD_DATA_FLAG) = _ThreadDataTemplate;
*thread_table_item = thread_data;
UnLock(&_ThreadMutex);
if (_ExitProcessNow) ExitProcess();
_CallFunctionPriority(init, init_end, false);
TStartData start_data;
_GetStartData(start_data, thread_data);
// _ApplyCommonColors(start_data.WinData);
(unsigned int&)thread_data[MENUET_THREAD_DATA_FLAG] |= 0x40000000;
thread_data[MENUET_THREAD_DATA_TITLE] = (void*)(&start_data);
if (!MenuetOnStart(start_data, thread_data)) return false;
(unsigned int&)thread_data[MENUET_THREAD_DATA_FLAG] &= ~0x40000000;
_SetStartData(start_data, thread_data);
return true;
}
void _RemoveThreadData(TThreadData thread_data, void *exit = 0, void *exit_end = 0)
{
_CallFunctionPriority(exit, exit_end, true);
volatile TThreadData *thread_table_item;
Lock(&_ThreadMutex);
if (_ExitProcessNow) ExitProcess();
thread_table_item = &_ThreadTable[_HashByte(GetPid(thread_data))];
while (*thread_table_item)
{
if (*thread_table_item == thread_data)
{
*thread_table_item = (TThreadData)thread_data[MENUET_THREAD_DATA_NEXT];
break;
}
thread_table_item = (TThreadData*)(*thread_table_item + MENUET_THREAD_DATA_NEXT);
}
UnLock(&_ThreadMutex);
if (_ExitProcessNow) ExitProcess();
}
void GetWindowData(TWindowData &win_data, TThreadData thread_data)
{
if ((unsigned int)thread_data[MENUET_THREAD_DATA_FLAG] & 0x40000000)
{
win_data = ((TStartData*)thread_data[MENUET_THREAD_DATA_TITLE])->WinData;
return;
}
win_data.WindowType = (unsigned short)((unsigned int)thread_data[MENUET_THREAD_DATA_C_WINDOW] >> 24);
win_data.HeaderType = (unsigned short)((unsigned int)thread_data[MENUET_THREAD_DATA_C_HEADER] >> 24);
win_data.WindowColor = (unsigned int)thread_data[MENUET_THREAD_DATA_C_WINDOW] & 0xFFFFFF;
win_data.HeaderColor = (unsigned int)thread_data[MENUET_THREAD_DATA_C_HEADER] & 0xFFFFFF;
win_data.BorderColor = (unsigned int)thread_data[MENUET_THREAD_DATA_C_BORDER] & 0xFFFFFF;
win_data.TitleColor = (unsigned int)thread_data[MENUET_THREAD_DATA_C_TITLE] & 0xFFFFFF;
win_data.Title = (char*)thread_data[MENUET_THREAD_DATA_TITLE];
}
void SetWindowData(const TWindowData &win_data, TThreadData thread_data)
{
if ((unsigned int)thread_data[MENUET_THREAD_DATA_FLAG] & 0x40000000)
{
((TStartData*)thread_data[MENUET_THREAD_DATA_TITLE])->WinData = win_data;
return;
}
(unsigned int&)thread_data[MENUET_THREAD_DATA_C_WINDOW] =
((unsigned int)win_data.WindowType << 24) | (win_data.WindowColor & 0xFFFFFF);
(unsigned int&)thread_data[MENUET_THREAD_DATA_C_HEADER] =
((unsigned int)win_data.HeaderType << 24) | (win_data.HeaderColor & 0xFFFFFF);
(unsigned int&)thread_data[MENUET_THREAD_DATA_C_BORDER] = win_data.BorderColor & 0xFFFFFF;
(unsigned int&)thread_data[MENUET_THREAD_DATA_C_TITLE] = win_data.TitleColor & 0xFFFFFF;
thread_data[MENUET_THREAD_DATA_TITLE] = (void*)win_data.Title;
Invalidate(1, thread_data);
}
void CloseWindow(TThreadData thread_data)
{
(unsigned int&)thread_data[MENUET_THREAD_DATA_FLAG] |= 0x80000000;
}
void Invalidate(int frame, TThreadData thread_data)
{
if (frame < 0) return;
(unsigned int&)thread_data[MENUET_THREAD_DATA_FLAG] |= (frame ? 3 : 1);
}
void* GetPicture(unsigned short &width, unsigned short &height, TThreadData thread_data)
{
width = (unsigned short)((unsigned int)thread_data[MENUET_THREAD_DATA_SZ_PICT] >> 16);
height = (unsigned short)((unsigned int)thread_data[MENUET_THREAD_DATA_SZ_PICT]);
return (void*)thread_data[MENUET_THREAD_DATA_PICTURE];
}
void SetPicture(void *picture, unsigned short width, unsigned short height, TThreadData thread_data)
{
thread_data[MENUET_THREAD_DATA_PICTURE] = (void*)picture;
(unsigned int&)thread_data[MENUET_THREAD_DATA_SZ_PICT] =
(width == 0 || height == 0) ? 0 : (((unsigned int)width << 16) | height);
Invalidate(0, thread_data);
}
int _GetSkinHeader();
void GetBorderHeader(unsigned short &border_size, unsigned short &header_size, TThreadData thread_data)
{
int win_type = ((unsigned int)thread_data[MENUET_THREAD_DATA_FLAG] & 0x40000000) ?
((TStartData*)thread_data[MENUET_THREAD_DATA_TITLE])->WinData.WindowType :
((unsigned int)thread_data[MENUET_THREAD_DATA_C_WINDOW] >> 24);
border_size = MENUET_BORDER_SIZE;
header_size = short(((win_type & 15) == 3) ? _GetSkinHeader() : MENUET_HEADER_SIZE);
}
void GetClientSize(unsigned short &width, unsigned short &height,
int win_width, int win_height, TThreadData thread_data)
{
const int MAX_SIZE = 32767;
unsigned short border_size, header_size;
GetBorderHeader(border_size, header_size, thread_data);
win_width -= 2 * border_size;
win_height -= border_size + header_size;
if (win_width < 0) win_width = 0;
else if (win_width > MAX_SIZE) win_width = MAX_SIZE;
if (win_height < 0) win_height = 0;
else if (win_height > MAX_SIZE) win_height = MAX_SIZE;
width = (unsigned short)win_width;
height = (unsigned short)win_height;
}
void GetMousePosPicture(short &x, short &y)
{
unsigned short dx, dy;
GetMousePosition(x, y);
GetBorderHeader(dx, dy);
x -= dx; y -= dy;
}
}
#else // def __MENUET__
namespace Menuet
{
struct TMutex
{
unsigned int mut;
TMutex();
~TMutex();
};
#undef MENUET_MUTEX_INIT
#define MENUET_MUTEX_INIT TMutex()
struct TRecMutex
{
unsigned int mut;
TRecMutex();
~TRecMutex();
};
#undef MENUET_REC_MUTEX_INIT
#define MENUET_REC_MUTEX_INIT TRecMutex()
}
#endif // else: def __MENUET__
#endif // ndef __MENUET_H_INCLUDED_

View File

@ -1,13 +0,0 @@
#ifndef __STDARG_H
#define __STDARG_H
typedef void *va_list;
#define __size(x) ((sizeof(x)+sizeof(int)-1) & ~(sizeof(int)-1))
#define va_start(ap, parmN) ((void)((ap) = (va_list)((char *)(&parmN)+__size(parmN))))
#define va_arg(ap, type) (*(type *)(((*(char **)&(ap))+=__size(type))-(__size(type))))
#define va_end(ap) ((void)0)
#endif /* __STDARG_H */

View File

@ -1,49 +0,0 @@
macro writestr [arg]
{
common
local straddr
local strend
pushad
push straddr
push strend
jmp @Menuet@DebugPutString$qpxc
straddr db arg,0
strend:
pop eax
popad
}
macro writeint arg
{
push dword arg
xchg eax,[esp]
pushad
push eax
call @DebugPutNumber$qi
pop eax
popad
pop eax
}
macro write [arg]
{
forward
if arg eq
else if arg eq endline
writestr 10
else if arg eqtype ''
writestr arg
else
writeint arg
end if
}
macro writeln [arg]
{
common
write arg,endline
}

View File

@ -1,10 +0,0 @@
;//NAME// checkers.cpp
;//COMPILER// bcc32 -S -v- -R- -6 -a4 -O2 -Og -Oi -Ov -OS -k- -D__MENUET__ -Iinclude
;//UTIL_PATH// .
STACKSIZE equ 102400
HEAPSIZE equ 102400
include "include\me_start.inc"
include "include\me_func.inc"
include "include\me_heap.inc"

View File

@ -1,79 +0,0 @@
unsigned long cur_color;
class TKlbrGraphDraw : public TGraphDraw
{
public:
virtual int SetColor(unsigned long c) {cur_color=c;return 1;}
virtual int DrawLine(int x0, int y0, int x1, int y1);
virtual int DrawText(int x0, int y0, char* text);
virtual int IsDraw(void) {return 1;}
virtual int DrawClear();
virtual unsigned long CreateColor(unsigned short red,
unsigned short green, unsigned short blue);
virtual void GetSize(int &w, int &h);
virtual int GetTextH(const char *s) {return 10;}
virtual int GetTextW(const char *s) {return 6 * strlen(s);}
virtual void Quit(int q = 1) {CloseWindow();}
};
int TKlbrGraphDraw::DrawLine(int x0, int y0, int x1, int y1)
{
asm mov ebx, x0
asm shl ebx, 16
asm add ebx, x1
asm mov ecx, y0
asm shl ecx, 16
asm add ecx, y1
asm mov edx, [cur_color]
asm push 38
asm pop eax
asm int 40h
return 1;
}
int TKlbrGraphDraw::DrawText(int x0, int y0, char* text)
{
asm mov ebx, x0
asm shl ebx, 16
asm add ebx, y0
asm mov ecx, [cur_color]
asm or ecx, 0xC0000000
asm mov edx, text
asm mov edi, 0xFFFFFF
asm push 4
asm pop eax
asm int 40h
return 1;
}
int TKlbrGraphDraw::DrawClear(void)
{
int w,h;
GetSize(w,h);
asm mov ebx, w
asm mov ecx, h
asm mov edx, 0xFFFFFF
asm push 13
asm pop eax
asm int 40h
return 1;
}
unsigned long TKlbrGraphDraw::CreateColor(unsigned short red,
unsigned short green, unsigned short blue)
{
return (unsigned long)(blue >> 8) + ((unsigned long)(green >> 8) << 8) +
((unsigned long)(red >> 8) << 16);
}
void TKlbrGraphDraw::GetSize(int &w, int &h)
{
int width, height;
asm sub esp, 1024
asm mov ebx, esp
asm or ecx, -1
asm push 9
asm pop eax
asm int 40h
asm mov eax, [esp+62]
asm mov width, eax
asm mov eax, [esp+66]
asm mov height, eax
asm add esp, 1024
w = width;
h = height;
}

View File

@ -3,11 +3,9 @@
#include "position.h" #include "position.h"
#include "sysproc.h" #include "sysproc.h"
#ifndef __MENUET__
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <assert.h> #include <assert.h>
#endif
template <class tvalue> template <class tvalue>
class TBaseCompPlayer : public TChPlayer class TBaseCompPlayer : public TChPlayer

View File

@ -1,12 +1,10 @@
#ifndef _HEADER_POSITION_H #ifndef _HEADER_POSITION_H
#define _HEADER_POSITION_H #define _HEADER_POSITION_H
#ifndef __MENUET__
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#endif
#define NELEM(a) (sizeof(a) / sizeof((a)[0])) #define NELEM(a) (sizeof(a) / sizeof((a)[0]))
@ -226,7 +224,7 @@ char *Position::WriteMv(const unsigned char mv[], char WP[], int how)
int x, y; int x, y;
NumToPole(mv[i], x, y); NumToPole(mv[i], x, y);
WP[j++] = char('a' + NW_CELL - 1 - x); WP[j++] = char('a' + NW_CELL - 1 - x);
int r = sprintf(WP + j, "%d", 1 + y); int r = itoa(WP + j, 1 + y);
if (r > 0) j += r; if (r > 0) j += r;
if (i != nmv) WP[j++] = '-'; if (i != nmv) WP[j++] = '-';
} }
@ -333,7 +331,7 @@ int Position::WriteMvEx(const unsigned char mv[], char WP[], int how) const
if (WP) if (WP)
{ {
WP[L++] = char('a' + NW_CELL - 1 - x0); WP[L++] = char('a' + NW_CELL - 1 - x0);
int r = sprintf(WP + L, "%d", 1 + y0); int r = itoa(WP + L, 1 + y0);
if (r > 0) L += r; if (r > 0) L += r;
} }
else else

View File

@ -1,331 +0,0 @@
static void shortsort(char *lo, char *hi, unsigned width,
int (*comp)(const void *, const void *));
static void swap(char *p, char *q, unsigned width);
/* this parameter defines the cutoff between using quick sort and
insertion sort for arrays; arrays with lengths shorter or equal to the
below value use insertion sort */
#define CUTOFF 8 /* testing shows that this is good value */
#define STKSIZ (8*sizeof(void*) - 2)
/***
*qsort(base, num, wid, comp) - quicksort function for sorting arrays
*
*Purpose:
* quicksort the array of elements
* side effects: sorts in place
* maximum array size is number of elements times size of elements,
* but is limited by the virtual address space of the processor
*
*Entry:
* char *base = pointer to base of array
* unsigned num = number of elements in the array
* unsigned width = width in bytes of each array element
* int (*comp)() = pointer to function returning analog of strcmp for
* strings, but supplied by user for comparing the array elements.
* it accepts 2 pointers to elements.
* Returns neg if 1<2, 0 if 1=2, pos if 1>2.
*
*Exit:
* returns void
*
*******************************************************************************/
void qsort (
void *base,
unsigned num,
unsigned width,
int (*comp)(const void *, const void *)
)
{
/* Note: the number of stack entries required is no more than
1 + log2(num), so 30 is sufficient for any array */
char *lo, *hi; /* ends of sub-array currently sorting */
char *mid; /* points to middle of subarray */
char *loguy, *higuy; /* traveling pointers for partition step */
unsigned size; /* size of the sub-array */
char *lostk[STKSIZ], *histk[STKSIZ];
int stkptr; /* stack for saving sub-array to be processed */
if (num < 2)
return; /* nothing to do */
stkptr = 0; /* initialize stack */
lo = (char *)base;
hi = (char *)base + width * (num-1); /* initialize limits */
/* this entry point is for pseudo-recursion calling: setting
lo and hi and jumping to here is like recursion, but stkptr is
preserved, locals aren't, so we preserve stuff on the stack */
recurse:
size = (hi - lo) / width + 1; /* number of el's to sort */
/* below a certain size, it is faster to use a O(n^2) sorting method */
if (size <= CUTOFF) {
shortsort(lo, hi, width, comp);
}
else {
/* First we pick a partitioning element. The efficiency of the
algorithm demands that we find one that is approximately the median
of the values, but also that we select one fast. We choose the
median of the first, middle, and last elements, to avoid bad
performance in the face of already sorted data, or data that is made
up of multiple sorted runs appended together. Testing shows that a
median-of-three algorithm provides better performance than simply
picking the middle element for the latter case. */
mid = lo + (size / 2) * width; /* find middle element */
/* Sort the first, middle, last elements into order */
if (comp(lo, mid) > 0) {
swap(lo, mid, width);
}
if (comp(lo, hi) > 0) {
swap(lo, hi, width);
}
if (comp(mid, hi) > 0) {
swap(mid, hi, width);
}
/* We now wish to partition the array into three pieces, one consisting
of elements <= partition element, one of elements equal to the
partition element, and one of elements > than it. This is done
below; comments indicate conditions established at every step. */
loguy = lo;
higuy = hi;
/* Note that higuy decreases and loguy increases on every iteration,
so loop must terminate. */
for (;;) {
/* lo <= loguy < hi, lo < higuy <= hi,
A[i] <= A[mid] for lo <= i <= loguy,
A[i] > A[mid] for higuy <= i < hi,
A[hi] >= A[mid] */
/* The doubled loop is to avoid calling comp(mid,mid), since some
existing comparison funcs don't work when passed the same
value for both pointers. */
if (mid > loguy) {
do {
loguy += width;
} while (loguy < mid && comp(loguy, mid) <= 0);
}
if (mid <= loguy) {
do {
loguy += width;
} while (loguy <= hi && comp(loguy, mid) <= 0);
}
/* lo < loguy <= hi+1, A[i] <= A[mid] for lo <= i < loguy,
either loguy > hi or A[loguy] > A[mid] */
do {
higuy -= width;
} while (higuy > mid && comp(higuy, mid) > 0);
/* lo <= higuy < hi, A[i] > A[mid] for higuy < i < hi,
either higuy == lo or A[higuy] <= A[mid] */
if (higuy < loguy)
break;
/* if loguy > hi or higuy == lo, then we would have exited, so
A[loguy] > A[mid], A[higuy] <= A[mid],
loguy <= hi, higuy > lo */
swap(loguy, higuy, width);
/* If the partition element was moved, follow it. Only need
to check for mid == higuy, since before the swap,
A[loguy] > A[mid] implies loguy != mid. */
if (mid == higuy)
mid = loguy;
/* A[loguy] <= A[mid], A[higuy] > A[mid]; so condition at top
of loop is re-established */
}
/* A[i] <= A[mid] for lo <= i < loguy,
A[i] > A[mid] for higuy < i < hi,
A[hi] >= A[mid]
higuy < loguy
implying:
higuy == loguy-1
or higuy == hi - 1, loguy == hi + 1, A[hi] == A[mid] */
/* Find adjacent elements equal to the partition element. The
doubled loop is to avoid calling comp(mid,mid), since some
existing comparison funcs don't work when passed the same value
for both pointers. */
higuy += width;
if (mid < higuy) {
do {
higuy -= width;
} while (higuy > mid && comp(higuy, mid) == 0);
}
if (mid >= higuy) {
do {
higuy -= width;
} while (higuy > lo && comp(higuy, mid) == 0);
}
/* OK, now we have the following:
higuy < loguy
lo <= higuy <= hi
A[i] <= A[mid] for lo <= i <= higuy
A[i] == A[mid] for higuy < i < loguy
A[i] > A[mid] for loguy <= i < hi
A[hi] >= A[mid] */
/* We've finished the partition, now we want to sort the subarrays
[lo, higuy] and [loguy, hi].
We do the smaller one first to minimize stack usage.
We only sort arrays of length 2 or more.*/
if ( higuy - lo >= hi - loguy ) {
if (lo < higuy) {
lostk[stkptr] = lo;
histk[stkptr] = higuy;
++stkptr;
} /* save big recursion for later */
if (loguy < hi) {
lo = loguy;
goto recurse; /* do small recursion */
}
}
else {
if (loguy < hi) {
lostk[stkptr] = loguy;
histk[stkptr] = hi;
++stkptr; /* save big recursion for later */
}
if (lo < higuy) {
hi = higuy;
goto recurse; /* do small recursion */
}
}
}
/* We have sorted the array, except for any pending sorts on the stack.
Check if there are any, and do them. */
--stkptr;
if (stkptr >= 0) {
lo = lostk[stkptr];
hi = histk[stkptr];
goto recurse; /* pop subarray from stack */
}
else
return; /* all subarrays done */
}
/***
*shortsort(hi, lo, width, comp) - insertion sort for sorting short arrays
*shortsort_s(hi, lo, width, comp, context) - insertion sort for sorting short arrays
*
*Purpose:
* sorts the sub-array of elements between lo and hi (inclusive)
* side effects: sorts in place
* assumes that lo < hi
*
*Entry:
* char *lo = pointer to low element to sort
* char *hi = pointer to high element to sort
* unsigned width = width in bytes of each array element
* int (*comp)() = pointer to function returning analog of strcmp for
* strings, but supplied by user for comparing the array elements.
* it accepts 2 pointers to elements, together with a pointer to a context
* (if present). Returns neg if 1<2, 0 if 1=2, pos if 1>2.
* void *context - pointer to the context in which the function is
* called. This context is passed to the comparison function.
*
*Exit:
* returns void
*
*Exceptions:
*
*******************************************************************************/
static void shortsort (
char *lo,
char *hi,
unsigned width,
int (*comp)(const void *, const void *)
)
{
char *p, *max;
/* Note: in assertions below, i and j are alway inside original bound of
array to sort. */
while (hi > lo) {
/* A[i] <= A[j] for i <= j, j > hi */
max = lo;
for (p = lo+width; p <= hi; p += width) {
/* A[i] <= A[max] for lo <= i < p */
if (comp(p, max) > 0) {
max = p;
}
/* A[i] <= A[max] for lo <= i <= p */
}
/* A[i] <= A[max] for lo <= i <= hi */
swap(max, hi, width);
/* A[i] <= A[hi] for i <= hi, so A[i] <= A[j] for i <= j, j >= hi */
hi -= width;
/* A[i] <= A[j] for i <= j, j > hi, loop top condition established */
}
/* A[i] <= A[j] for i <= j, j > lo, which implies A[i] <= A[j] for i < j,
so array is sorted */
}
/***
*swap(a, b, width) - swap two elements
*
*Purpose:
* swaps the two array elements of size width
*
*Entry:
* char *a, *b = pointer to two elements to swap
* unsigned width = width in bytes of each array element
*
*Exit:
* returns void
*
*Exceptions:
*
*******************************************************************************/
static void swap (
char *a,
char *b,
unsigned width
)
{
char tmp;
if ( a != b )
/* Do the swap one character at a time to avoid potential alignment
problems. */
while ( width-- ) {
tmp = *a;
*a++ = *b;
*b++ = tmp;
}
}

View File

@ -1,19 +1,23 @@
#ifndef _HEADER_SYSTEM_PROCESS_H #ifndef _HEADER_SYSTEM_PROCESS_H
#define _HEADER_SYSTEM_PROCESS_H #define _HEADER_SYSTEM_PROCESS_H
#ifndef __MENUET__
#include <stdlib.h> #include <stdlib.h>
#include <time.h> #include <time.h>
#endif
#if defined __GNUC__ #if defined _KOLIBRI
# define DIR_SEPARATOR ('/')
inline long GetProcessId() {return 0;}
inline long DuplicateProcess() {return -1;}
inline int random(int m) {return ((unsigned long)rand()) % m;}
inline void randomize() {srand(__menuet__getsystemclock());}
#elif defined __GNUC__
# include <unistd.h> # include <unistd.h>
# define DIR_SEPARATOR ('/') # define DIR_SEPARATOR ('/')
inline long GetProcessId() {return (long)getpid();} inline long GetProcessId() {return (long)getpid();}
inline long DuplicateProcess() {return (long)fork();} inline long DuplicateProcess() {return (long)fork();}
inline int random(int m) {return ((unsigned long)rand()) % m;} inline int random(int m) {return ((unsigned long)rand()) % m;}
inline void randomize() {srand(time(0));} inline void randomize() {srand(time(0));}
#elif defined __TURBOC__ && !defined __MENUET__ #elif defined __TURBOC__
# include <process.h> # include <process.h>
# define DIR_SEPARATOR ('\\') # define DIR_SEPARATOR ('\\')
inline long GetProcessId() {return (long)getpid();} inline long GetProcessId() {return (long)getpid();}

View File

@ -19,8 +19,9 @@
#define main OwlMain #define main OwlMain
class TWinGraphDraw : public TGraphDraw class TWinGraphDraw : public TBaseGraphDraw<TWinGraphDraw>
{ {
typedef TBaseGraphDraw<TWinGraphDraw> TGraphDraw;
public: public:
TWinGraphDraw(const char *s = 0); TWinGraphDraw(const char *s = 0);
~TWinGraphDraw(); ~TWinGraphDraw();

View File

@ -1,4 +1,6 @@
CFLAGS = "-Os -fno-ident -fomit-frame-pointer -fno-stack-check -fno-stack-protector -mno-stack-arg-probe -mpreferred-stack-boundary=2 -fno-exceptions -fno-asynchronous-unwind-tables -ffast-math -mno-ms-bitfields" CFLAGS = "-Os -fno-ident -fomit-frame-pointer -fno-stack-check -fno-stack-protector -mno-stack-arg-probe -mpreferred-stack-boundary=2 -fno-exceptions -fno-asynchronous-unwind-tables -ffast-math -mno-ms-bitfields -march=pentium-mmx"
CFLAGS_c = "" -- extra flags for *.c
CFLAGS_cpp = " -fno-rtti" -- extra flags for *.cpp
LDFLAGS = "-nostdlib -n --file-alignment=16 --section-alignment=16" LDFLAGS = "-nostdlib -n --file-alignment=16 --section-alignment=16"
INCLUDES = "" INCLUDES = ""
LIBS = "" LIBS = ""
@ -8,7 +10,7 @@ OBJS = {}
function compile_gcc(input, output) function compile_gcc(input, output)
if not output then output = '%B.o' end if not output then output = '%B.o' end
tup.append_table(OBJS, tup.append_table(OBJS,
tup.foreach_rule(input, "kos32-gcc -c " .. CFLAGS .. " " .. INCLUDES .. " -o %o %f", output) tup.foreach_rule(input, "kos32-gcc -c " .. CFLAGS .. "$(CFLAGS_%e) " .. INCLUDES .. " -o %o %f", output)
) )
end end