<commit_before>#include "CONTROL_S.H"

#include "DRAW.H"
#include "SPECIFIC.H"

void DrawBinoculars()
{
	S_Warn("[DrawBinoculars] - Unimplemented!\n");
}

int GetChange(struct ITEM_INFO* item, struct ANIM_STRUCT* anim)//7D48C
{
	struct CHANGE_STRUCT* change;//$t1
	struct RANGE_STRUCT* range;//$v1
	int i;//$t2
	int j;//$t0

	if (item->current_anim_state == item->goal_anim_state)
	{
		//locret_7D51C
		return 0;
	}

	change = &changes[anim->change_index];

	if (anim->number_changes <= 0)
	{
		//locret_7D51C
		return 0;
	}

	//loc_7D4C4
	do
	{
		j = 0;
		if (change->goal_anim_state == item->goal_anim_state && change->number_ranges > 0)
		{
			range = &ranges[change->range_index];

			//loc_7D4E4
			do
			{
				if (item->frame_number < range->start_frame)
				{
					//loc_7D4FC
					j++;
					if (j < change->number_ranges)
					{
						range++;
						continue;
					}
					else
					{
						break;
					}
				}
				else if (range->end_frame >= item->frame_number)
				{
					//loc_7D524
					item->anim_number = range->link_anim_num;
					item->frame_number = range->link_frame_num;
					return 1;
				}
			} while (1);
		}
		//loc_7D50C
		i++;
		change++;
	} while (i < anim->number_changes);

	//locret_7D51C
	return 0;
}

void AnimateLara(struct ITEM_INFO* item /* s1 */)//7D53C(<)
{
	struct ANIM_STRUCT* anim = &anims[item->anim_number];//$s2

	item->frame_number += 1;
	//v0 = anim->number_changes

	if (anim->number_changes > 0 && GetChange())
	{

	}//loc_7D5BC

#if 0
move    $a0, $s1
jal     sub_7D48C
move    $a1, $s2
beqz    $v0, loc_7D5BC
nop
lh      $v1, 0x14($s1)
lw      $a0, 0x202C($gp)
sll     $v0, $v1, 2
addu    $v0, $v1
sll     $v0, 3
addu    $s2, $a0, $v0
lh      $v1, 6($s2)
nop
sh      $v1, 0xE($s1)

loc_7D5BC:
lh      $v1, 0x16($s1)
lh      $v0, 0x1A($s2)
nop
slt     $v0, $v1
beqz    $v0, loc_7D6D4
nop
lh      $s3, 0x24($s2)
lh      $v0, 0x26($s2)
lw      $v1, 0x2078($gp)
blez    $s3, loc_7D6A4
sll     $v0, 1
addu    $s0, $v1, $v0

loc_7D5EC:
lhu     $v0, 0($s0)
addiu   $s0, 2
addiu   $at, $v0, -1
beqz    $at, loc_7D628
addiu   $at, $v0, -2
beqz    $at, loc_7D650
addiu   $at, $v0, -3
beqz    $at, loc_7D684
addiu   $at, $v0, -5
beqz    $at, loc_7D620
addiu   $at, $v0, -6
bnez    $at, loc_7D698
nop

loc_7D620:
j       loc_7D698
addiu   $s0, 4

loc_7D628:
move    $a0, $s1
lh      $a1, 0($s0)
lh      $a2, 2($s0)
lh      $a3, 4($s0)
jal     sub_7D410
addiu   $s0, 6
move    $a0, $s1
li      $a1, 0xFFFFFE83
jal     sub_7C58C
addiu   $ra, 0x48

loc_7D650:
lw      $v1, 0x84($s1)
lhu     $at, 0($s0)
lhu     $v0, 2($s0)
lh      $a0, 0x5232($gp)
addiu   $s0, 4
ori     $v1, 8
sh      $at, 0x20($s1)
sh      $v0, 0x1E($s1)
beqz    $a0, loc_7D698
sw      $v1, 0x84($s1)
sh      $a0, 0x20($s1)
j       loc_7D698
sh      $zero, 0x5232($gp)

loc_7D684:
lh      $v1, 0x522A($gp)
li      $v0, 5
beq     $v1, $v0, loc_7D698
nop
sh      $zero, 0x522A($gp)

loc_7D698:
addiu   $s3, -1
bgtz    $s3, loc_7D5EC
nop

loc_7D6A4:
lh      $at, 0x1C($s2)
lhu     $a0, 0x1E($s2)
lw      $v0, 0x202C($gp)
sh      $at, 0x14($s1)
sh      $a0, 0x16($s1)
sll     $v1, $at, 2
addu    $v1, $at
sll     $v1, 3
addu    $s2, $v0, $v1
lh      $v0, 6($s2)
nop
sh      $v0, 0xE($s1)

loc_7D6D4:
lh      $s3, 0x24($s2)
lh      $v0, 0x26($s2)
lw      $v1, 0x2078($gp)
blez    $s3, loc_7D7C8
sll     $v0, 1
addu    $s0, $v1, $v0

loc_7D6EC:
lhu     $v0, 0($s0)
addiu   $s0, 2
addiu   $at, $v0, -2
beqz    $at, loc_7D7B8
addiu   $at, $v0, -5
beqz    $at, loc_7D720
addiu   $at, $v0, -6
beqz    $at, loc_7D780
addiu   $at, $v0, -1
bnez    $at, loc_7D7BC
nop
j       loc_7D7BC
addiu   $s0, 6

loc_7D720:
lh      $v1, 0x16($s1)
lh      $v0, 0($s0)
lhu     $a0, 2($s0)
bne     $v1, $v0, loc_7D7B8
andi    $a1, $a0, 0xC000
beqz    $a1, loc_7D76C
li      $v0, 0x4000
lw      $v1, 0x5270($gp)
bne     $a1, $v0, loc_7D754
nop
bgez    $v1, loc_7D76C
li      $v0, 0xFFFF8100
beq     $v1, $v0, loc_7D76C

loc_7D754:
li      $v0, 0x8000
bne     $a1, $v0, loc_7D7B8
nop
bgez    $v1, loc_7D7B8
li      $v0, 0xFFFF8100
beq     $v1, $v0, loc_7D7B8

loc_7D76C:
andi    $a0, 0x3FFF
addiu   $a1, $s1, 0x40
li      $a2, 2
jal     sub_91780
addiu   $ra, 0x38

loc_7D780:
lh      $at, 0x16($s1)
lh      $v0, 0($s0)
lui     $v1, 9
bne     $at, $v0, loc_7D7B8
la      $v1, off_92AE8
lhu     $a1, 2($s0)
move    $a0, $s1
andi    $a3, $a1, 0x3FFF
sll     $v0, $a3, 2
addu    $v0, $v1
lw      $a2, 0($v0)
andi    $a1, 0xC000
jalr    $a2
sh      $a1, 0x1AAC($gp)

loc_7D7B8:
addiu   $s0, 4

loc_7D7BC:
addiu   $s3, -1
bgtz    $s3, loc_7D6EC
nop

loc_7D7C8:
lw      $a1, 0x14($s2)
lw      $s0, 0x10($s2)
lh      $t1, 0x16($s1)
lh      $v0, 0x18($s2)
beqz    $a1, loc_7D7EC
subu    $t1, $v0
mult    $a1, $t1
mflo    $v0
addu    $s0, $v0

loc_7D7EC:
lw      $v0, 0x84($s1)
nop
andi    $v0, 8
bnez    $v0, loc_7D828
sra     $s0, 16
lw      $a1, 0xC($s2)
lw      $a0, 8($s2)
beqz    $a1, loc_7D820
sra     $v0, $a0, 16
mult    $a1, $t1
mflo    $v0
addu    $a0, $v0
sra     $v0, $a0, 16

loc_7D820:
j       loc_7D884
sh      $v0, 0x1E($s1)

loc_7D828:
lw      $a2, 0xC($s2)
addiu   $v0, $t1, -1
mult    $a2, $v0
lhu     $a1, 0x1E($s1)
lw      $v1, 8($s2)
mflo    $a0
addu    $a0, $v1, $a0
sra     $v0, $a0, 16
subu    $a1, $v0
addu    $a0, $a2
sra     $v0, $a0, 16
lh      $a0, 0x20($s1)
addu    $a1, $v0
sh      $a1, 0x1E($s1)
slti    $v0, $a0, 0x80
beqz    $v0, loc_7D870
addiu   $v0, $a0, 1
addiu   $v0, $a0, 6

loc_7D870:
sh      $v0, 0x20($s1)
lw      $v1, 0x44($s1)
nop
addu    $v1, $v0
sw      $v1, 0x44($s1)

loc_7D884:
lw      $v1, 0x532C($gp)
li      $v0, 0xFFFFFFFF
beq     $v1, $v0, loc_7D89C
nop
jal     sub_4B3D8
move    $a0, $s1

loc_7D89C:
lw      $v0, 0x526C($gp)
lui     $t0, 9
andi    $v0, 0x20
bnez    $v0, loc_7D934
la      $t0, dword_9A8C8
lhu     $a2, 0x52CE($gp)
lh      $a3, 0x1E($s1)
srl     $at, $a2, 2
andi    $at, 0x3FFC
addu    $at, $t0
lh      $v0, 0($at)
lh      $at, 2($at)
mult    $v0, $a3
lw      $t2, 0x40($s1)
lw      $t3, 0x48($s1)
mflo    $v0
sra     $v0, 12
addu    $t2, $v0
mult    $at, $a3
addiu   $a2, 0x4000
sra     $a2, 2
andi    $a2, 0x3FFC
addu    $a2, $t0
lh      $v1, 0($a2)
lh      $a0, 2($a2)
mflo    $at
sra     $at, 12
addu    $t3, $at
mult    $v1, $s0
mflo    $v1
sra     $v1, $v0, 12
addu    $t2, $v1
mult    $a0, $s0
sw      $t2, 0x40($s1)
mflo    $a0
sra     $a0, 12
addu    $t3, $a0
sw      $t3, 0x48($s1)

loc_7D934:
lw      $ra, 0x24+var_4($sp)
lw      $s3, 0x24+var_8($sp)
lw      $s2, 0x24+var_C($sp)
lw      $s1, 0x24+var_10($sp)
lw      $s0, 0x24+var_14($sp)
jr      $ra
addiu   $sp, 0x24
#endif
	UNIMPLEMENTED();
}<commit_msg>[Specific-PSXPC_N] Implement TranslateItem.<commit_after>#include "CONTROL_S.H"

#include "CAMERA.H"
#include "COLLIDE_S.H"
#include "DRAW.H"
#include "SPECIFIC.H"

void DrawBinoculars()
{
	S_Warn("[DrawBinoculars] - Unimplemented!\n");
}

void TranslateItem(struct ITEM_INFO* item, unsigned short x, unsigned short y, unsigned short z)
{
	short sin;//$v1
	short cos;//$t0

	cos = COS(item->pos.y_rot);
	sin = SIN(item->pos.y_rot);

	item->pos.x_pos += ((cos * x) + (sin * z)) >> W2V_SHIFT;
	item->pos.y_pos += y;
	item->pos.z_pos += ((-sin * x) + (cos * z)) >> W2V_SHIFT;
}

int GetChange(struct ITEM_INFO* item, struct ANIM_STRUCT* anim)//7D48C
{
	struct CHANGE_STRUCT* change;//$t1
	struct RANGE_STRUCT* range;//$v1
	int i;//$t2
	int j;//$t0

	if (item->current_anim_state == item->goal_anim_state)
	{
		//locret_7D51C
		return 0;
	}

	change = &changes[anim->change_index];

	if (anim->number_changes <= 0)
	{
		//locret_7D51C
		return 0;
	}

	//loc_7D4C4
	do
	{
		j = 0;
		if (change->goal_anim_state == item->goal_anim_state && change->number_ranges > 0)
		{
			range = &ranges[change->range_index];

			//loc_7D4E4
			do
			{
				if (item->frame_number < range->start_frame)
				{
					//loc_7D4FC
					j++;
					if (j < change->number_ranges)
					{
						range++;
						continue;
					}
					else
					{
						break;
					}
				}
				else if (range->end_frame >= item->frame_number)
				{
					//loc_7D524
					item->anim_number = range->link_anim_num;
					item->frame_number = range->link_frame_num;
					return 1;
				}
			} while (1);
		}
		//loc_7D50C
		i++;
		change++;
	} while (i < anim->number_changes);

	//locret_7D51C
	return 0;
}

void AnimateLara(struct ITEM_INFO* item /* s1 */)//7D53C(<)
{
	struct ANIM_STRUCT* anim = &anims[item->anim_number];//$s2
	unsigned short* command;//$s0
	unsigned short data;//$v0

	item->frame_number += 1;
	//v0 = anim->number_changes

	if (anim->number_changes > 0 && GetChange(item, anim))
	{
		//v1 = item->anim_number
		//a0 = &anims[item->anim_number];
		anim = &anims[item->anim_number];///@TODO Not really required
		item->current_anim_state = anim->current_anim_state;
	}
	//loc_7D5BC
	//v1 = item->frame_number
	//v0 = anim->frame_end

	if (anim->frame_end < item->frame_number)
	{
		//s3 = anim->number_commands
		//v0 = anim->command_index
		//v1 = commands

		if (anim->number_commands > 0)
		{
			command = (unsigned short*)&commands[anim->command_index];

			//loc_7D5EC
			data = *command++;

			if (data - 1 == 0)
			{
				//loc_7D628
				TranslateItem(item, command[0], command[1], command[2]);
				command += 3;
				UpdateLaraRoom(item, -381);
			}
			else if (data - 2 == 0)
			{
				//loc_7D650
			}
			else if (data - 3 == 0)
			{
				//loc_7D684
			}
			else if (data - 5 == 0 || data - 6 == 0)
			{
				//loc_7D620
			}

			//loc_7D698

		}//loc_7D6A4
	}//loc_7D6D4

#if 0
addiu   $at, $v0, -1
beqz    $at, loc_7D628
addiu   $at, $v0, -2
beqz    $at, loc_7D650
addiu   $at, $v0, -3
beqz    $at, loc_7D684
addiu   $at, $v0, -5
beqz    $at, loc_7D620
addiu   $at, $v0, -6
bnez    $at, loc_7D698
nop

loc_7D620:
j       loc_7D698
addiu   $s0, 4

loc_7D650:
lw      $v1, 0x84($s1)
lhu     $at, 0($s0)
lhu     $v0, 2($s0)
lh      $a0, 0x5232($gp)
addiu   $s0, 4
ori     $v1, 8
sh      $at, 0x20($s1)
sh      $v0, 0x1E($s1)
beqz    $a0, loc_7D698
sw      $v1, 0x84($s1)
sh      $a0, 0x20($s1)
j       loc_7D698
sh      $zero, 0x5232($gp)

loc_7D684:
lh      $v1, 0x522A($gp)
li      $v0, 5
beq     $v1, $v0, loc_7D698
nop
sh      $zero, 0x522A($gp)

loc_7D698:
addiu   $s3, -1
bgtz    $s3, loc_7D5EC
nop

loc_7D6A4:
lh      $at, 0x1C($s2)
lhu     $a0, 0x1E($s2)
lw      $v0, 0x202C($gp)
sh      $at, 0x14($s1)
sh      $a0, 0x16($s1)
sll     $v1, $at, 2
addu    $v1, $at
sll     $v1, 3
addu    $s2, $v0, $v1
lh      $v0, 6($s2)
nop
sh      $v0, 0xE($s1)

loc_7D6D4:
lh      $s3, 0x24($s2)
lh      $v0, 0x26($s2)
lw      $v1, 0x2078($gp)
blez    $s3, loc_7D7C8
sll     $v0, 1
addu    $s0, $v1, $v0

loc_7D6EC:
lhu     $v0, 0($s0)
addiu   $s0, 2
addiu   $at, $v0, -2
beqz    $at, loc_7D7B8
addiu   $at, $v0, -5
beqz    $at, loc_7D720
addiu   $at, $v0, -6
beqz    $at, loc_7D780
addiu   $at, $v0, -1
bnez    $at, loc_7D7BC
nop
j       loc_7D7BC
addiu   $s0, 6

loc_7D720:
lh      $v1, 0x16($s1)
lh      $v0, 0($s0)
lhu     $a0, 2($s0)
bne     $v1, $v0, loc_7D7B8
andi    $a1, $a0, 0xC000
beqz    $a1, loc_7D76C
li      $v0, 0x4000
lw      $v1, 0x5270($gp)
bne     $a1, $v0, loc_7D754
nop
bgez    $v1, loc_7D76C
li      $v0, 0xFFFF8100
beq     $v1, $v0, loc_7D76C

loc_7D754:
li      $v0, 0x8000
bne     $a1, $v0, loc_7D7B8
nop
bgez    $v1, loc_7D7B8
li      $v0, 0xFFFF8100
beq     $v1, $v0, loc_7D7B8

loc_7D76C:
andi    $a0, 0x3FFF
addiu   $a1, $s1, 0x40
li      $a2, 2
jal     sub_91780
addiu   $ra, 0x38

loc_7D780:
lh      $at, 0x16($s1)
lh      $v0, 0($s0)
lui     $v1, 9
bne     $at, $v0, loc_7D7B8
la      $v1, off_92AE8
lhu     $a1, 2($s0)
move    $a0, $s1
andi    $a3, $a1, 0x3FFF
sll     $v0, $a3, 2
addu    $v0, $v1
lw      $a2, 0($v0)
andi    $a1, 0xC000
jalr    $a2
sh      $a1, 0x1AAC($gp)

loc_7D7B8:
addiu   $s0, 4

loc_7D7BC:
addiu   $s3, -1
bgtz    $s3, loc_7D6EC
nop

loc_7D7C8:
lw      $a1, 0x14($s2)
lw      $s0, 0x10($s2)
lh      $t1, 0x16($s1)
lh      $v0, 0x18($s2)
beqz    $a1, loc_7D7EC
subu    $t1, $v0
mult    $a1, $t1
mflo    $v0
addu    $s0, $v0

loc_7D7EC:
lw      $v0, 0x84($s1)
nop
andi    $v0, 8
bnez    $v0, loc_7D828
sra     $s0, 16
lw      $a1, 0xC($s2)
lw      $a0, 8($s2)
beqz    $a1, loc_7D820
sra     $v0, $a0, 16
mult    $a1, $t1
mflo    $v0
addu    $a0, $v0
sra     $v0, $a0, 16

loc_7D820:
j       loc_7D884
sh      $v0, 0x1E($s1)

loc_7D828:
lw      $a2, 0xC($s2)
addiu   $v0, $t1, -1
mult    $a2, $v0
lhu     $a1, 0x1E($s1)
lw      $v1, 8($s2)
mflo    $a0
addu    $a0, $v1, $a0
sra     $v0, $a0, 16
subu    $a1, $v0
addu    $a0, $a2
sra     $v0, $a0, 16
lh      $a0, 0x20($s1)
addu    $a1, $v0
sh      $a1, 0x1E($s1)
slti    $v0, $a0, 0x80
beqz    $v0, loc_7D870
addiu   $v0, $a0, 1
addiu   $v0, $a0, 6

loc_7D870:
sh      $v0, 0x20($s1)
lw      $v1, 0x44($s1)
nop
addu    $v1, $v0
sw      $v1, 0x44($s1)

loc_7D884:
lw      $v1, 0x532C($gp)
li      $v0, 0xFFFFFFFF
beq     $v1, $v0, loc_7D89C
nop
jal     sub_4B3D8
move    $a0, $s1

loc_7D89C:
lw      $v0, 0x526C($gp)
lui     $t0, 9
andi    $v0, 0x20
bnez    $v0, loc_7D934
la      $t0, dword_9A8C8
lhu     $a2, 0x52CE($gp)
lh      $a3, 0x1E($s1)
srl     $at, $a2, 2
andi    $at, 0x3FFC
addu    $at, $t0
lh      $v0, 0($at)
lh      $at, 2($at)
mult    $v0, $a3
lw      $t2, 0x40($s1)
lw      $t3, 0x48($s1)
mflo    $v0
sra     $v0, 12
addu    $t2, $v0
mult    $at, $a3
addiu   $a2, 0x4000
sra     $a2, 2
andi    $a2, 0x3FFC
addu    $a2, $t0
lh      $v1, 0($a2)
lh      $a0, 2($a2)
mflo    $at
sra     $at, 12
addu    $t3, $at
mult    $v1, $s0
mflo    $v1
sra     $v1, $v0, 12
addu    $t2, $v1
mult    $a0, $s0
sw      $t2, 0x40($s1)
mflo    $a0
sra     $a0, 12
addu    $t3, $a0
sw      $t3, 0x48($s1)

loc_7D934:
lw      $ra, 0x24+var_4($sp)
lw      $s3, 0x24+var_8($sp)
lw      $s2, 0x24+var_C($sp)
lw      $s1, 0x24+var_10($sp)
lw      $s0, 0x24+var_14($sp)
jr      $ra
addiu   $sp, 0x24
#endif
	UNIMPLEMENTED();
}<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: FWS.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: rt $ $Date: 2003-10-06 15:43:20 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _FOREIGN_WINDOW_SYSTEM_HXX
#define _FOREIGN_WINDOW_SYSTEM_HXX

#include <X11/Xlib.h>

#if defined(__cplusplus)
extern "C" {
#endif

/* Initialize our atoms and determine if the current window manager is
 * providing FWS extension support.
 */

Bool
WMSupportsFWS (Display *display, int screen);

/* Send a client message to the FWS_COMM_WINDOW indicating the existance
 * of a new FWS client window.  Be careful to avoid BadWindow errors on
 * the XSendEvent in case the FWS_COMM_WINDOW root window property had
 * old/obsolete junk in it.
 */

Bool
RegisterFwsWindow (Display *display, Window window);

/* Add the FWS protocol atoms to the WMProtocols property for the window.
 */

void
AddFwsProtocols (Display *display, Window window);

#if defined(__cplusplus)
} /* extern "C" */
#endif

#endif // _FOREIGN_WINDOW_SYSTEM_HXX

<commit_msg>INTEGRATION: CWS ooo19126 (1.2.580); FILE MERGED 2005/09/05 14:46:17 rt 1.2.580.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: FWS.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-09 13:50:38 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _FOREIGN_WINDOW_SYSTEM_HXX
#define _FOREIGN_WINDOW_SYSTEM_HXX

#include <X11/Xlib.h>

#if defined(__cplusplus)
extern "C" {
#endif

/* Initialize our atoms and determine if the current window manager is
 * providing FWS extension support.
 */

Bool
WMSupportsFWS (Display *display, int screen);

/* Send a client message to the FWS_COMM_WINDOW indicating the existance
 * of a new FWS client window.  Be careful to avoid BadWindow errors on
 * the XSendEvent in case the FWS_COMM_WINDOW root window property had
 * old/obsolete junk in it.
 */

Bool
RegisterFwsWindow (Display *display, Window window);

/* Add the FWS protocol atoms to the WMProtocols property for the window.
 */

void
AddFwsProtocols (Display *display, Window window);

#if defined(__cplusplus)
} /* extern "C" */
#endif

#endif // _FOREIGN_WINDOW_SYSTEM_HXX

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: wntgdi.cxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: hr $ $Date: 2006-06-19 20:01:18 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#if defined _MSC_VER
#pragma warning(push, 1)
#endif
#include <windows.h>
#if defined _MSC_VER
#pragma warning(pop)
#endif

// -----------------------------------------------------------------------

extern "C"
{
BOOL WINAPI WIN_Rectangle( HDC hDC, int X1, int Y1, int X2, int Y2 )
{
    return Rectangle( hDC, X1, Y1, X2, Y2 );
}
}

// -----------------------------------------------------------------------

extern "C"
{
BOOL WINAPI WIN_Polygon( HDC hDC, CONST POINT * ppt, int ncnt )
{
    return Polygon( hDC, ppt, ncnt );
}
}

// -----------------------------------------------------------------------

extern "C"
{
BOOL WINAPI WIN_PolyPolygon( HDC hDC, CONST POINT * ppt, LPINT npcnt, int ncnt )
{
    return PolyPolygon( hDC, ppt, npcnt, ncnt );
}
}
<commit_msg>INTEGRATION: CWS pchfix02 (1.3.112); FILE MERGED 2006/09/01 17:58:14 kaib 1.3.112.1: #i68856# Added header markers and pch files<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: wntgdi.cxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-17 12:46:48 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"

#if defined _MSC_VER
#pragma warning(push, 1)
#endif
#include <windows.h>
#if defined _MSC_VER
#pragma warning(pop)
#endif

// -----------------------------------------------------------------------

extern "C"
{
BOOL WINAPI WIN_Rectangle( HDC hDC, int X1, int Y1, int X2, int Y2 )
{
    return Rectangle( hDC, X1, Y1, X2, Y2 );
}
}

// -----------------------------------------------------------------------

extern "C"
{
BOOL WINAPI WIN_Polygon( HDC hDC, CONST POINT * ppt, int ncnt )
{
    return Polygon( hDC, ppt, ncnt );
}
}

// -----------------------------------------------------------------------

extern "C"
{
BOOL WINAPI WIN_PolyPolygon( HDC hDC, CONST POINT * ppt, LPINT npcnt, int ncnt )
{
    return PolyPolygon( hDC, ppt, npcnt, ncnt );
}
}
<|endoftext|>


<commit_before>#ifndef __V_PLAY_HPP__
#define __V_PLAY_HPP__
#include "utility.hpp"
#include "debug.hpp"
#include "videotype.hpp"

using namespace UtilityLib;

typedef BOOL (*VPlayDataHandler)(void* pData, VideoFrame& packet);
typedef BOOL (*VPlayPBTimeCallback)(void* pData, int time);

typedef BOOL (*VPlayRawFrameHandler)(void* pData, RawFrame& frame);

typedef enum __VPlayCmd
{
	VPLAY_CMD_PLAY = 1,
	VPLAY_CMD_PAUSE,
	VPLAY_CMD_SPEED,
	VPLAY_CMD_MOVE,
	VPLAY_CMD_LAST
}VPlayCmd;

typedef struct __VPlayCmdParam
{
	int speed;
	int moveto;
}VPlayCmdParam;

class VPlayData;
class VE_LIBRARY_API VPlay
{
public:

	VPlay();
	~VPlay();
public:
	static BOOL SetLicense(astring &strLicense);
	static BOOL GetLicenseInfo(astring &strHostId, int &ch, int &type);
public:
	BOOL Init(BOOL bRealStream, string strUrl, string strUser, string strPass);
	BOOL Init(string strFile);
	BOOL AttachWidget(HWND hWnd, int w, int h);
	BOOL UpdateWidget(HWND hWnd, int w, int h);
	BOOL DetachWidget(HWND hWnd);
	BOOL SetPbTimeCallback(HWND hWnd, void * pData, VPlayPBTimeCallback callback);
	BOOL Control(VPlayCmd cmd, VPlayCmdParam param);
	BOOL EnablePtz(HWND hWnd, bool enable);
	BOOL DrawPtzDirection(HWND hWnd, int x1, int y1, int x2,  int y2);
	BOOL ClearPtzDirection(HWND hWnd);

	BOOL StartGetData(void * pData, VPlayDataHandler callback);
	BOOL StopGetData();
	BOOL StartGetRawFrame(void * pData, VPlayRawFrameHandler callback);
	BOOL StopGetRawFrame();
	BOOL PutRawData(VideoFrame& packet);
	BOOL ShowAlarm(HWND hWnd);

public:
    VPlayData * m_data;
};
#endif /* __V_PLAY_HPP__ */
<commit_msg>add  intel media sdk<commit_after>#ifndef __V_PLAY_HPP__
#define __V_PLAY_HPP__
#include "utility.hpp"
#include "debug.hpp"
#include "videotype.hpp"

using namespace UtilityLib;

typedef BOOL (*VPlayDataHandler)(void* pData, VideoFrame& packet);
typedef BOOL (*VPlayPBTimeCallback)(void* pData, int time);

typedef BOOL (*VPlayRawFrameHandler)(void* pData, RawFrame& frame);

typedef enum __VPlayCmd
{
	VPLAY_CMD_PLAY = 1,
	VPLAY_CMD_PAUSE,
	VPLAY_CMD_SPEED,
	VPLAY_CMD_MOVE,
	VPLAY_CMD_LAST
}VPlayCmd;

typedef struct __VPlayCmdParam
{
	int speed;
	int moveto;
}VPlayCmdParam;

class VPlayData;
class VE_LIBRARY_API VPlay
{
public:

	VPlay();
	~VPlay();
public:
	static BOOL SetLicense(astring &strLicense);
	static BOOL GetLicenseInfo(astring &strHostId, int &ch, int &type);
public:
	BOOL Init(BOOL bRealStream, string strUrl, string strUser, string strPass, BOOL bHWAccel = FALSE);
	BOOL Init(string strFile, BOOL bHWAccel = FALSE);
	BOOL AttachWidget(HWND hWnd, int w, int h);
	BOOL UpdateWidget(HWND hWnd, int w, int h);
	BOOL DetachWidget(HWND hWnd);
	BOOL SetPbTimeCallback(HWND hWnd, void * pData, VPlayPBTimeCallback callback);
	BOOL Control(VPlayCmd cmd, VPlayCmdParam param);
	BOOL EnablePtz(HWND hWnd, bool enable);
	BOOL DrawPtzDirection(HWND hWnd, int x1, int y1, int x2,  int y2);
	BOOL ClearPtzDirection(HWND hWnd);

	BOOL StartGetData(void * pData, VPlayDataHandler callback);
	BOOL StopGetData();
	BOOL StartGetRawFrame(void * pData, VPlayRawFrameHandler callback);
	BOOL StopGetRawFrame();
	BOOL PutRawData(VideoFrame& packet);
	BOOL ShowAlarm(HWND hWnd);

public:
    VPlayData * m_data;
};
#endif /* __V_PLAY_HPP__ */
<|endoftext|>


<commit_before>#pragma once
#include "PageFrameAllocator.hpp"
#include "PageTable.hpp"

class MMU
{
public:
    MMU(uint32_t mmap_addr, uint32_t mmap_length);
    void *palloc(size_t numberOfPages);
    int pfree(void *startOfMemoryRange, size_t numberOfPages);
    void install();
private:
    PageFrameAllocator _pageFrameAllocator;
    PageTable _pageDirectory;
};
<commit_msg>Gave palloc()/pfree() default page count of 1.<commit_after>#pragma once
#include "PageFrameAllocator.hpp"
#include "PageTable.hpp"

class MMU
{
public:
    MMU(uint32_t mmap_addr, uint32_t mmap_length);
    void *palloc(size_t numberOfPages = 1);
    int pfree(void *startOfMemoryRange, size_t numberOfPages = 1);
    void install();
private:
    PageFrameAllocator _pageFrameAllocator;
    PageTable _pageDirectory;
};
<|endoftext|>


<commit_before>#include <QtWidgets/QHBoxLayout>
#include <QtCore/QString>

#include "gridParameters.h"
#include "../../../qrkernel/settingsManager.h"

GridParameters::GridParameters(QWidget *parent)
	: QFrame(parent)
{
	QHBoxLayout *layout = new QHBoxLayout(this);

	mShowGridCheckBox = new QCheckBox(this);
	QString const checkBoxTitle = tr("Show grid");
	mShowGridCheckBox->setText(checkBoxTitle);
	mShowGridCheckBox->setTristate(false);

	mCellSize = new QSlider(this);
	mCellSize->setOrientation(Qt::Horizontal);
	mCellSize->setMinimum(50);
	mCellSize->setMaximum(200);
	mCellSize->setTickInterval(10);
	mCellSize->setEnabled(false);

	layout->addWidget(mShowGridCheckBox);
	layout->addWidget(mCellSize);
	layout->setContentsMargins(5, 5, 5, 5);

	connect(mShowGridCheckBox, SIGNAL(toggled(bool)), mCellSize, SLOT(setEnabled(bool)));
	connect(mShowGridCheckBox, SIGNAL(toggled(bool)), this, SLOT(showGrid(bool)));
	connect(mCellSize, SIGNAL(valueChanged(int)), this, SLOT(setCellSize(int)));

	setLayout(layout);

	showGrid(qReal::SettingsManager::value("2dShowGrid").toBool());
	setCellSize(qReal::SettingsManager::value("2dGridCellSize").toInt());
}

GridParameters::~GridParameters()
{
}

void GridParameters::showGrid(bool isGridEnabled)
{
	qReal::SettingsManager::setValue("2dShowGrid", isGridEnabled);
	emit parametersChanged();
}

void GridParameters::setCellSize(int cellSizeValue)
{
	qReal::SettingsManager::setValue("2dGridCellSize", cellSizeValue);
	emit parametersChanged();
}
<commit_msg>Fixed grid initialization in 2D model<commit_after>#include <QtWidgets/QHBoxLayout>
#include <QtCore/QString>

#include "gridParameters.h"
#include "../../../qrkernel/settingsManager.h"

GridParameters::GridParameters(QWidget *parent)
	: QFrame(parent)
{
	QHBoxLayout *layout = new QHBoxLayout(this);

	mShowGridCheckBox = new QCheckBox(this);
	QString const checkBoxTitle = tr("Show grid");
	mShowGridCheckBox->setText(checkBoxTitle);
	mShowGridCheckBox->setTristate(false);

	mCellSize = new QSlider(this);
	mCellSize->setOrientation(Qt::Horizontal);
	mCellSize->setMinimum(50);
	mCellSize->setMaximum(200);
	mCellSize->setTickInterval(10);
	mCellSize->setEnabled(false);

	layout->addWidget(mShowGridCheckBox);
	layout->addWidget(mCellSize);
	layout->setContentsMargins(5, 5, 5, 5);

	connect(mShowGridCheckBox, SIGNAL(toggled(bool)), mCellSize, SLOT(setEnabled(bool)));
	connect(mShowGridCheckBox, SIGNAL(toggled(bool)), this, SLOT(showGrid(bool)));
	connect(mCellSize, SIGNAL(valueChanged(int)), this, SLOT(setCellSize(int)));

	bool const showGrid = qReal::SettingsManager::value("2dShowGrid").toBool();
	int const gridSize = qReal::SettingsManager::value("2dGridCellSize").toInt();
	mShowGridCheckBox->setChecked(showGrid);
	mCellSize->setValue(gridSize);

	setLayout(layout);

}

GridParameters::~GridParameters()
{
}

void GridParameters::showGrid(bool isGridEnabled)
{
	qReal::SettingsManager::setValue("2dShowGrid", isGridEnabled);
	emit parametersChanged();
}

void GridParameters::setCellSize(int cellSizeValue)
{
	qReal::SettingsManager::setValue("2dGridCellSize", cellSizeValue);
	emit parametersChanged();
}
<|endoftext|>


<commit_before>//---------------------------------------------------------------------------
// hexanoise/generator_opencl.cpp
//
// Copyright 2014, nocte@hippie.nu            Released under the MIT License.
//---------------------------------------------------------------------------

#include "generator_opencl.hpp"

#include <iostream>
#include <cmath>
#include <fstream>
#include <stdexcept>
#include "node.hpp"

#ifndef OPENCL_OCTAVES_LIMIT
# define OPENCL_OCTAVES_LIMIT 16
#endif

namespace hexa {
namespace noise {

generator_opencl::generator_opencl (const generator_context& ctx,
                                    cl::Context& opencl_context,
                                    cl::Device&  opencl_device,
                                    const node& n,
                                    const std::string& opencl_file)
    : generator_i(ctx)
    , count_(1)
    , context_(opencl_context)
    , device_(opencl_device)
    , queue_ (opencl_context, opencl_device)
{
    std::string body (co(n));

    std::ifstream file (opencl_file.c_str(), std::ios::binary);
    if (!file)
        throw std::runtime_error("cannot open OpenCL file " + opencl_file);

    file.seekg(0, std::ios::end);
    main_.resize(file.tellg());
    file.seekg(0, std::ios::beg);
    file.read(&main_[0], main_.size());
    file.close();

    main_ += "\n";
    for (auto& p : functions_)
    {
        main_ += p;
        main_ += "\n\n";
    }
    main_ += "\n" \
    "__kernel void noisemain(\n" \
    "  __global double* output, const double2 start, const double2 step)\n" \
    "{\n"\
    "    int2 coord = (int2)(get_global_id(0), get_global_id(1));\n"\
    "    int  sizex = get_global_size(0);\n"\
    "    double2 p = mad(step, (double2)(coord.x, coord.y), start);\n" \
    "    output[coord.y * sizex + coord.x] = ";

    main_ += body;
    main_ += ";\n}\n";

    main_ += "\n" \
    "__kernel void noisemain_int16(\n" \
    "  __global int16* output, const double2 start, const double2 step)\n" \
    "{\n"\
    "    int2 coord = (int2)(get_global_id(0), get_global_id(1));\n"\
    "    int  sizex = get_global_size(0);\n"\
    "    double2 p = mad(step, (double2)(coord.x, coord.y), start);\n" \
    "    output[coord.y * sizex + coord.x] = (int16)(";

    main_ += body;
    main_ += ");\n}\n";

    std::vector<cl::Device> device_vec;
    device_vec.emplace_back(opencl_device);

    cl::Program::Sources sources (1, { main_.c_str(), main_.size() });
    program_ = cl::Program(opencl_context, sources);
    try
    {
        program_.build(device_vec, "-cl-strict-aliasing -cl-mad-enable -cl-unsafe-math-optimizations -cl-fast-relaxed-math");
    }
    catch (cl::Error&)
    {
        std::cerr << program_.getBuildInfo<CL_PROGRAM_BUILD_LOG>(opencl_device) << std::endl;
        throw;
    }

    kernel_       = cl::Kernel(program_, "noisemain");
    kernel_int16_ = cl::Kernel(program_, "noisemain_int16");
}

std::vector<double>
generator_opencl::run (const glm::dvec2& corner,
                       const glm::dvec2& step,
                       const glm::ivec2& count)
{
    unsigned int width (count.x), height (count.y);
    unsigned int elements (width * height);

    std::vector<double> result (elements);
    cl::Buffer output (context_, CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
                       elements * sizeof(double),
                       &result[0]);

    kernel_.setArg(0, output);
    kernel_.setArg(1, sizeof(corner), (void*)&corner);
    kernel_.setArg(2, sizeof(step),   (void*)&step);

    queue_.enqueueNDRangeKernel(kernel_, cl::NullRange, {width, height},
                                cl::NullRange);

    auto memobj (queue_.enqueueMapBuffer(output, true, CL_MAP_WRITE, 0,
                                         elements * sizeof(double)));

    queue_.enqueueUnmapMemObject(output, memobj);

    return result;
}

std::vector<int16_t>
generator_opencl::run_int16 (const glm::dvec2& corner,
                             const glm::dvec2& step,
                             const glm::ivec2& count)
{
    unsigned int width (count.x), height (count.y);
    unsigned int elements (width * height);

    std::vector<int16_t> result (elements);
    cl::Buffer output (context_, CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
                       elements * sizeof(int16_t),
                       &result[0]);

    kernel_int16_.setArg(0, output);
    kernel_int16_.setArg(1, sizeof(corner), (void*)&corner);
    kernel_int16_.setArg(2, sizeof(step),   (void*)&step);

    queue_.enqueueNDRangeKernel(kernel_int16_, cl::NullRange, {width, height},
                                cl::NullRange);

    auto memobj (queue_.enqueueMapBuffer(output, true, CL_MAP_WRITE, 0,
                                         elements * sizeof(int16_t)));

    queue_.enqueueUnmapMemObject(output, memobj);

    return result;
}

std::string generator_opencl::pl (const node& n)
{
    std::string result ("(");
    for (auto i (n.input.begin()); i != n.input.end(); )
    {
        result += co(*i);
        ++i;
        if (i != n.input.end())
            result.push_back(',');
    }
    result += ')';
    return result;
}

std::string generator_opencl::co (const node& n)
{
    switch (n.type)
    {
    case node::entry_point:     return "p";
    case node::const_var:       return std::to_string(n.aux_var);
    case node::const_bool:      return std::to_string(n.aux_bool);
    case node::const_str:       throw std::runtime_error("string encountered");

    case node::rotate:          return "p_rotate" + pl(n);
    case node::scale:           return "("+co(n.input[0])+"/"+co(n.input[1])+")";
    case node::shift:           return "("+co(n.input[0])+"+"+co(n.input[1])+")";
    case node::swap:            return "p_swap" + pl(n);

    case node::map:
    {
        std::string func_name ("p_map" + std::to_string(count_++));

        std::stringstream func_body;
        func_body
        << "inline double2 " << func_name << " (const double2 p) { return (double2)("
        << co(n.input[1]) << ", "
        << co(n.input[2]) << "); }" << std::endl;

        functions_.emplace_back(func_body.str());

        return func_name + "("+ co(n.input[0]) + ")";
    }

    case node::turbulence:
    {
        std::string func_name ("p_map" + std::to_string(count_++));

        std::stringstream func_body;
        func_body
        << "inline double2 " << func_name << " (const double2 p) { return (double2)("
        << "p.x+(" << co(n.input[1]) << "), "
        << "p.y+(" << co(n.input[2]) << ")); }" << std::endl;

        functions_.emplace_back(func_body.str());

        return func_name + "("+ co(n.input[0]) + ")";
    }

    case node::worley:
    {
        std::string func_name ("p_worley" + std::to_string(count_++));

        std::stringstream func_body;
        func_body
        << "inline double " << func_name << " (const double2 q, uint seed) { "
        << "  double2 p = p_worley(q, seed);"
        << "  return " << co(n.input[1]) << "; }" << std::endl;

        functions_.emplace_back(func_body.str());
        return func_name + "("+co(n.input[0])+ ","+co(n.input[2])+")";
    }

    case node::voronoi:
    {
        std::string func_name ("p_voronoi" + std::to_string(count_++));

        std::stringstream func_body;
        func_body
        << "inline double " << func_name << " (const double2 q, uint seed) { "
        << "  double2 p = p_voronoi(q, seed);"
        << "  return " << co(n.input[1]) << "; }" << std::endl;

        functions_.emplace_back(func_body.str());
        return func_name + "("+co(n.input[0])+ ","+co(n.input[2])+")";
    }

    case node::angle:           return "p_angle" + pl(n);
    case node::chebyshev:       return "p_chebyshev" + pl(n);
    case node::checkerboard:    return "p_checkerboard" + pl(n);
    case node::distance:        return "length" + pl(n);
    case node::manhattan:       return "p_manhattan" + pl(n);
    case node::perlin:          return "p_perlin" + pl(n);
    case node::simplex:         return "p_simplex" + pl(n);
    case node::x:               return co(n.input[0])+".x";
    case node::y:               return co(n.input[0])+".y";

    case node::add:             return "("+co(n.input[0])+"+"+co(n.input[1])+")";
    case node::sub:             return "("+co(n.input[0])+"-"+co(n.input[1])+")";
    case node::mul:             return "("+co(n.input[0])+"*"+co(n.input[1])+")";
    case node::div:             return "("+co(n.input[0])+"/"+co(n.input[1])+")";

    case node::abs:             return "fabs" + pl(n);
    case node::blend:           return "p_blend" + pl(n);
    case node::cos:             return "cospi" + pl(n);
    case node::min:             return "fmin" + pl(n);
    case node::max:             return "fmax" + pl(n);
    case node::neg:             return "-" + co(n.input[0]);

    case node::pow:
    {
        if (n.input[1].is_const)
        {
            double exp (std::floor(n.input[1].aux_var));
            if (std::abs(exp - n.input[1].aux_var) < 1e-9)
                return "pown("+co(n.input[0])+","+std::to_string((int)exp)+")";
        }
        return "pow"+pl(n);
    }

    case node::range:           return "p_range" + pl(n);
    case node::round:           return "round" + pl(n);
    case node::saw:             return "p_saw" + pl(n);
    case node::sin:             return "sinpi" + pl(n);
    case node::sqrt:            return "sqrt" + pl(n);
    case node::tan:             return "tanpi" + pl(n);

    case node::band:            return co(n.input[0])+"&&"+co(n.input[1]);
    case node::bor:             return co(n.input[0])+"||"+co(n.input[1]);
    case node::bxor:            return co(n.input[0])+"^^"+co(n.input[1]);
    case node::bnot:            return "!"+co(n.input[0]);

    case node::is_equal:        return co(n.input[0])+"=="+co(n.input[1]);
    case node::is_greaterthan:  return co(n.input[0])+">"+co(n.input[1]);
    case node::is_gte:          return co(n.input[0])+">="+co(n.input[1]);
    case node::is_lessthan:     return co(n.input[0])+"<"+co(n.input[1]);
    case node::is_lte:          return co(n.input[0])+"<="+co(n.input[1]);

    case node::is_in_circle:    return "p_is_in_circle" + pl(n);
    case node::is_in_rectangle: return "p_is_in_rectangle" + pl(n);

    case node::then_else:
        return "("+co(n.input[0])+")?("+co(n.input[1])+"):("+co(n.input[2])+")";

    case node::fractal:
    {
        assert(n.input.size() == 5);
        if (!n.input[2].is_const)
            throw std::runtime_error("fractal octave count must be a constexpr");

        int octaves (std::min<int>(n.input[2].aux_var, OPENCL_OCTAVES_LIMIT));

        std::string func_name ("p_fractal_" + std::to_string(count_++));

        std::stringstream func_body;
        func_body
        << "double " << func_name << " (double2 p, const double lac, const double per) {"
        << "double result = 0.0; double div = 0.0; double step = 1.0;"
        << "for(int i = 0; i < " << octaves << "; ++i)"
        << "{"
        << "  result += " << co(n.input[1]) << " * step;"
        << "  div += step;"
        << "  step *= lac;"
        << "  p *= per;"
        << "  p.x += 12345.0;"
        << "}"
        << "return result / div;"
        << "}";

        functions_.emplace_back(func_body.str());

        return func_name + "("
               + co(n.input[0]) + "," + co(n.input[3]) + ","
               + co(n.input[4]) + ")";
    }

    case node::lambda_:
    {
        assert(n.input.size() == 2);
        std::string func_name ("p_lambda_" + std::to_string(count_++));

        std::stringstream func_body;
        func_body
        << "double " << func_name << " (double2 p) {"
        << "return " << co(n.input[1]) << ";}" << std::endl;

        functions_.emplace_back(func_body.str());

        return func_name +"("+ co(n.input[0])+")";
    }

    case node::external_:
        throw std::runtime_error("OpenCL @external not implemented yet");

    case node::curve_linear:
        throw std::runtime_error("OpenCL curve_linear not implemented yet");

    case node::curve_spline:
        throw std::runtime_error("OpenCL curve_spline not implemented yet");

    case node::png_lookup:
        throw std::runtime_error("OpenCL png_lookup not implemented yet");

    default:
        throw std::runtime_error("function not implemented in OpenCL yet");
    }

    return std::string();
}

}} // namespace hexa::noise
<commit_msg>Fixed bug in OpenCL 'shift'<commit_after>//---------------------------------------------------------------------------
// hexanoise/generator_opencl.cpp
//
// Copyright 2014, nocte@hippie.nu            Released under the MIT License.
//---------------------------------------------------------------------------

#include "generator_opencl.hpp"

#include <iostream>
#include <cmath>
#include <fstream>
#include <stdexcept>
#include "node.hpp"

#ifndef OPENCL_OCTAVES_LIMIT
# define OPENCL_OCTAVES_LIMIT 16
#endif

namespace hexa {
namespace noise {

generator_opencl::generator_opencl (const generator_context& ctx,
                                    cl::Context& opencl_context,
                                    cl::Device&  opencl_device,
                                    const node& n,
                                    const std::string& opencl_file)
    : generator_i(ctx)
    , count_(1)
    , context_(opencl_context)
    , device_(opencl_device)
    , queue_ (opencl_context, opencl_device)
{
    std::string body (co(n));

    std::ifstream file (opencl_file.c_str(), std::ios::binary);
    if (!file)
        throw std::runtime_error("cannot open OpenCL file " + opencl_file);

    file.seekg(0, std::ios::end);
    main_.resize(file.tellg());
    file.seekg(0, std::ios::beg);
    file.read(&main_[0], main_.size());
    file.close();

    main_ += "\n";
    for (auto& p : functions_)
    {
        main_ += p;
        main_ += "\n\n";
    }
    main_ += "\n" \
    "__kernel void noisemain(\n" \
    "  __global double* output, const double2 start, const double2 step)\n" \
    "{\n"\
    "    int2 coord = (int2)(get_global_id(0), get_global_id(1));\n"\
    "    int  sizex = get_global_size(0);\n"\
    "    double2 p = mad(step, (double2)(coord.x, coord.y), start);\n" \
    "    output[coord.y * sizex + coord.x] = ";

    main_ += body;
    main_ += ";\n}\n";

    main_ += "\n" \
    "__kernel void noisemain_int16(\n" \
    "  __global int16* output, const double2 start, const double2 step)\n" \
    "{\n"\
    "    int2 coord = (int2)(get_global_id(0), get_global_id(1));\n"\
    "    int  sizex = get_global_size(0);\n"\
    "    double2 p = mad(step, (double2)(coord.x, coord.y), start);\n" \
    "    output[coord.y * sizex + coord.x] = (int16)(";

    main_ += body;
    main_ += ");\n}\n";

    std::vector<cl::Device> device_vec;
    device_vec.emplace_back(opencl_device);

    cl::Program::Sources sources (1, { main_.c_str(), main_.size() });
    program_ = cl::Program(opencl_context, sources);
    try
    {
        program_.build(device_vec, "-cl-strict-aliasing -cl-mad-enable -cl-unsafe-math-optimizations -cl-fast-relaxed-math");
    }
    catch (cl::Error&)
    {
        std::cerr << program_.getBuildInfo<CL_PROGRAM_BUILD_LOG>(opencl_device) << std::endl;
        throw;
    }

    kernel_       = cl::Kernel(program_, "noisemain");
    kernel_int16_ = cl::Kernel(program_, "noisemain_int16");
}

std::vector<double>
generator_opencl::run (const glm::dvec2& corner,
                       const glm::dvec2& step,
                       const glm::ivec2& count)
{
    unsigned int width (count.x), height (count.y);
    unsigned int elements (width * height);

    std::vector<double> result (elements);
    cl::Buffer output (context_, CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
                       elements * sizeof(double),
                       &result[0]);

    kernel_.setArg(0, output);
    kernel_.setArg(1, sizeof(corner), (void*)&corner);
    kernel_.setArg(2, sizeof(step),   (void*)&step);

    queue_.enqueueNDRangeKernel(kernel_, cl::NullRange, {width, height},
                                cl::NullRange);

    auto memobj (queue_.enqueueMapBuffer(output, true, CL_MAP_WRITE, 0,
                                         elements * sizeof(double)));

    queue_.enqueueUnmapMemObject(output, memobj);

    return result;
}

std::vector<int16_t>
generator_opencl::run_int16 (const glm::dvec2& corner,
                             const glm::dvec2& step,
                             const glm::ivec2& count)
{
    unsigned int width (count.x), height (count.y);
    unsigned int elements (width * height);

    std::vector<int16_t> result (elements);
    cl::Buffer output (context_, CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,
                       elements * sizeof(int16_t),
                       &result[0]);

    kernel_int16_.setArg(0, output);
    kernel_int16_.setArg(1, sizeof(corner), (void*)&corner);
    kernel_int16_.setArg(2, sizeof(step),   (void*)&step);

    queue_.enqueueNDRangeKernel(kernel_int16_, cl::NullRange, {width, height},
                                cl::NullRange);

    auto memobj (queue_.enqueueMapBuffer(output, true, CL_MAP_WRITE, 0,
                                         elements * sizeof(int16_t)));

    queue_.enqueueUnmapMemObject(output, memobj);

    return result;
}

std::string generator_opencl::pl (const node& n)
{
    std::string result ("(");
    for (auto i (n.input.begin()); i != n.input.end(); )
    {
        result += co(*i);
        ++i;
        if (i != n.input.end())
            result.push_back(',');
    }
    result += ')';
    return result;
}

std::string generator_opencl::co (const node& n)
{
    switch (n.type)
    {
    case node::entry_point:     return "p";
    case node::const_var:       return std::to_string(n.aux_var);
    case node::const_bool:      return std::to_string(n.aux_bool);
    case node::const_str:       throw std::runtime_error("string encountered");

    case node::rotate:          return "p_rotate" + pl(n);
    case node::scale:           return "("+co(n.input[0])+"/"+co(n.input[1])+")";
    case node::shift:           return "("+co(n.input[0])+"+(double2)("+co(n.input[1])+","+co(n.input[2])+"))";
    case node::swap:            return "p_swap" + pl(n);

    case node::map:
    {
        std::string func_name ("p_map" + std::to_string(count_++));

        std::stringstream func_body;
        func_body
        << "inline double2 " << func_name << " (const double2 p) { return (double2)("
        << co(n.input[1]) << ", "
        << co(n.input[2]) << "); }" << std::endl;

        functions_.emplace_back(func_body.str());

        return func_name + "("+ co(n.input[0]) + ")";
    }

    case node::turbulence:
    {
        std::string func_name ("p_map" + std::to_string(count_++));

        std::stringstream func_body;
        func_body
        << "inline double2 " << func_name << " (const double2 p) { return (double2)("
        << "p.x+(" << co(n.input[1]) << "), "
        << "p.y+(" << co(n.input[2]) << ")); }" << std::endl;

        functions_.emplace_back(func_body.str());

        return func_name + "("+ co(n.input[0]) + ")";
    }

    case node::worley:
    {
        std::string func_name ("p_worley" + std::to_string(count_++));

        std::stringstream func_body;
        func_body
        << "inline double " << func_name << " (const double2 q, uint seed) { "
        << "  double2 p = p_worley(q, seed);"
        << "  return " << co(n.input[1]) << "; }" << std::endl;

        functions_.emplace_back(func_body.str());
        return func_name + "("+co(n.input[0])+ ","+co(n.input[2])+")";
    }

    case node::voronoi:
    {
        std::string func_name ("p_voronoi" + std::to_string(count_++));

        std::stringstream func_body;
        func_body
        << "inline double " << func_name << " (const double2 q, uint seed) { "
        << "  double2 p = p_voronoi(q, seed);"
        << "  return " << co(n.input[1]) << "; }" << std::endl;

        functions_.emplace_back(func_body.str());
        return func_name + "("+co(n.input[0])+ ","+co(n.input[2])+")";
    }

    case node::angle:           return "p_angle" + pl(n);
    case node::chebyshev:       return "p_chebyshev" + pl(n);
    case node::checkerboard:    return "p_checkerboard" + pl(n);
    case node::distance:        return "length" + pl(n);
    case node::manhattan:       return "p_manhattan" + pl(n);
    case node::perlin:          return "p_perlin" + pl(n);
    case node::simplex:         return "p_simplex" + pl(n);
    case node::x:               return co(n.input[0])+".x";
    case node::y:               return co(n.input[0])+".y";

    case node::add:             return "("+co(n.input[0])+"+"+co(n.input[1])+")";
    case node::sub:             return "("+co(n.input[0])+"-"+co(n.input[1])+")";
    case node::mul:             return "("+co(n.input[0])+"*"+co(n.input[1])+")";
    case node::div:             return "("+co(n.input[0])+"/"+co(n.input[1])+")";

    case node::abs:             return "fabs" + pl(n);
    case node::blend:           return "p_blend" + pl(n);
    case node::cos:             return "cospi" + pl(n);
    case node::min:             return "fmin" + pl(n);
    case node::max:             return "fmax" + pl(n);
    case node::neg:             return "-" + co(n.input[0]);

    case node::pow:
    {
        if (n.input[1].is_const)
        {
            double exp (std::floor(n.input[1].aux_var));
            if (std::abs(exp - n.input[1].aux_var) < 1e-9)
                return "pown("+co(n.input[0])+","+std::to_string((int)exp)+")";
        }
        return "pow"+pl(n);
    }

    case node::range:           return "p_range" + pl(n);
    case node::round:           return "round" + pl(n);
    case node::saw:             return "p_saw" + pl(n);
    case node::sin:             return "sinpi" + pl(n);
    case node::sqrt:            return "sqrt" + pl(n);
    case node::tan:             return "tanpi" + pl(n);

    case node::band:            return co(n.input[0])+"&&"+co(n.input[1]);
    case node::bor:             return co(n.input[0])+"||"+co(n.input[1]);
    case node::bxor:            return co(n.input[0])+"^^"+co(n.input[1]);
    case node::bnot:            return "!"+co(n.input[0]);

    case node::is_equal:        return co(n.input[0])+"=="+co(n.input[1]);
    case node::is_greaterthan:  return co(n.input[0])+">"+co(n.input[1]);
    case node::is_gte:          return co(n.input[0])+">="+co(n.input[1]);
    case node::is_lessthan:     return co(n.input[0])+"<"+co(n.input[1]);
    case node::is_lte:          return co(n.input[0])+"<="+co(n.input[1]);

    case node::is_in_circle:    return "p_is_in_circle" + pl(n);
    case node::is_in_rectangle: return "p_is_in_rectangle" + pl(n);

    case node::then_else:
        return "("+co(n.input[0])+")?("+co(n.input[1])+"):("+co(n.input[2])+")";

    case node::fractal:
    {
        assert(n.input.size() == 5);
        if (!n.input[2].is_const)
            throw std::runtime_error("fractal octave count must be a constexpr");

        int octaves (std::min<int>(n.input[2].aux_var, OPENCL_OCTAVES_LIMIT));

        std::string func_name ("p_fractal_" + std::to_string(count_++));

        std::stringstream func_body;
        func_body
        << "double " << func_name << " (double2 p, const double lac, const double per) {"
        << "double result = 0.0; double div = 0.0; double step = 1.0;"
        << "for(int i = 0; i < " << octaves << "; ++i)"
        << "{"
        << "  result += " << co(n.input[1]) << " * step;"
        << "  div += step;"
        << "  step *= lac;"
        << "  p *= per;"
        << "  p.x += 12345.0;"
        << "}"
        << "return result / div;"
        << "}";

        functions_.emplace_back(func_body.str());

        return func_name + "("
               + co(n.input[0]) + "," + co(n.input[3]) + ","
               + co(n.input[4]) + ")";
    }

    case node::lambda_:
    {
        assert(n.input.size() == 2);
        std::string func_name ("p_lambda_" + std::to_string(count_++));

        std::stringstream func_body;
        func_body
        << "double " << func_name << " (double2 p) {"
        << "return " << co(n.input[1]) << ";}" << std::endl;

        functions_.emplace_back(func_body.str());

        return func_name +"("+ co(n.input[0])+")";
    }

    case node::external_:
        throw std::runtime_error("OpenCL @external not implemented yet");

    case node::curve_linear:
        throw std::runtime_error("OpenCL curve_linear not implemented yet");

    case node::curve_spline:
        throw std::runtime_error("OpenCL curve_spline not implemented yet");

    case node::png_lookup:
        throw std::runtime_error("OpenCL png_lookup not implemented yet");

    default:
        throw std::runtime_error("function not implemented in OpenCL yet");
    }

    return std::string();
}

}} // namespace hexa::noise
<|endoftext|>


<commit_before>/**
 * @file cache.cpp
 *
 */

#include "cache.h"
#include "info.h"
#include "logger.h"
#include "plugin_factory.h"
#include <boost/lexical_cast.hpp>
#include <time.h>

using namespace std;
using namespace himan::plugin;

typedef lock_guard<mutex> Lock;

std::mutex itsCheckMutex;

cache::cache() { itsLogger = logger("cache"); }
string cache::UniqueName(const info& info)
{
	string producer_id = boost::lexical_cast<string>(info.Producer().Id());
	string forecast_time = info.Time().OriginDateTime().String("%Y-%m-%d_%H:%M:%S");
	string valid_time = info.Time().ValidDateTime().String("%Y-%m-%d_%H:%M:%S");
	string param = info.Param().Name();
	string level_value = boost::lexical_cast<string>(info.Level().Value());
	string level = HPLevelTypeToString.at(info.Level().Type());
	string forecast_type = boost::lexical_cast<string>(info.ForecastType().Type());
	string forecast_type_value = boost::lexical_cast<string>(info.ForecastType().Value());
	return producer_id + '_' + forecast_time + '_' + valid_time + '_' + param + '_' + level + '_' + level_value + '_' +
	       forecast_type + '_' + forecast_type_value;
}

string cache::UniqueNameFromOptions(search_options& options)
{
	ASSERT(options.configuration->DatabaseType() == kNoDatabase || options.prod.Id() != kHPMissingInt);
	string producer_id = boost::lexical_cast<string>(options.prod.Id());
	string forecast_time = options.time.OriginDateTime().String("%Y-%m-%d_%H:%M:%S");
	string valid_time = options.time.ValidDateTime().String("%Y-%m-%d_%H:%M:%S");
	string param = options.param.Name();
	string level_value = boost::lexical_cast<string>((options.level).Value());
	string level = HPLevelTypeToString.at(options.level.Type());
	string forecast_type = boost::lexical_cast<string>(options.ftype.Type());
	string forecast_type_value = boost::lexical_cast<string>(options.ftype.Value());
	return producer_id + "_" + forecast_time + '_' + valid_time + '_' + param + '_' + level + '_' + level_value + '_' +
	       forecast_type + '_' + forecast_type_value;
}

void cache::Insert(info& anInfo, bool pin) { SplitToPool(anInfo, pin); }
void cache::SplitToPool(info& anInfo, bool pin)
{
	auto localInfo = anInfo;

	// Cached data is never replaced by another data that has
	// the same uniqueName

	string uniqueName = UniqueName(localInfo);

	{
		Lock lock(itsCheckMutex);

		if (cache_pool::Instance()->Find(uniqueName))
		{
			// New item, but only one thread should insert it (prevent race condition)

			itsLogger.Trace("Data with key " + uniqueName + " already exists at cache");

			// Update timestamp of this cache item
			cache_pool::Instance()->UpdateTime(uniqueName);
			return;
		}
	}

#ifdef HAVE_CUDA
	if (localInfo.Grid()->IsPackedData())
	{
		itsLogger.Trace("Removing packed data from cached info");
		localInfo.Grid()->PackedData().Clear();
	}
#endif

	ASSERT(!localInfo.Grid()->IsPackedData());

	vector<param> params;
	vector<level> levels;
	vector<forecast_time> times;
	vector<forecast_type> ftype;

	params.push_back(localInfo.Param());
	levels.push_back(localInfo.Level());
	times.push_back(localInfo.Time());
	ftype.push_back(localInfo.ForecastType());

	auto newInfo = make_shared<info>(localInfo);

	newInfo->Params(params);
	newInfo->Levels(levels);
	newInfo->Times(times);
	newInfo->ForecastTypes(ftype);
	newInfo->Create(localInfo.Grid());

	ASSERT(uniqueName == UniqueName(*newInfo));

	{
		Lock lock(itsCheckMutex);
		cache_pool::Instance()->Insert(uniqueName, newInfo, pin);
	}
}

vector<shared_ptr<himan::info>> cache::GetInfo(search_options& options)
{
	string uniqueName = UniqueNameFromOptions(options);

	vector<shared_ptr<himan::info>> info;

	if (cache_pool::Instance()->Find(uniqueName))
	{
		info.push_back(cache_pool::Instance()->GetInfo(uniqueName));
		itsLogger.Trace("Found matching data for " + uniqueName);
	}

	return info;
}

void cache::Clean() { cache_pool::Instance()->Clean(); }
size_t cache::Size() const { return cache_pool::Instance()->Size(); }
cache_pool* cache_pool::itsInstance = NULL;

cache_pool::cache_pool() : itsCacheLimit(-1) { itsLogger = logger("cache_pool"); }

cache_pool* cache_pool::Instance()
{
	if (!itsInstance)
	{
		itsInstance = new cache_pool();
	}

	return itsInstance;
}

void cache_pool::CacheLimit(int theCacheLimit) { itsCacheLimit = theCacheLimit; }
bool cache_pool::Find(const string& uniqueName) { return itsCache.count(uniqueName) > 0; }
void cache_pool::Insert(const string& uniqueName, shared_ptr<himan::info> anInfo, bool pin)
{
	Lock lock(itsInsertMutex);

	cache_item item;
	item.info = anInfo;
	item.access_time = time(nullptr);
	item.pinned = pin;

	itsCache.insert(pair<string, cache_item>(uniqueName, item));
	itsLogger.Trace("Data added to cache with name: " + uniqueName + ", pinned: " + boost::lexical_cast<string>(pin));

	if (itsCacheLimit > -1 && itsCache.size() > static_cast<size_t>(itsCacheLimit))
	{
		Clean();
	}
}

void cache_pool::UpdateTime(const std::string& uniqueName) { itsCache[uniqueName].access_time = time(nullptr); }
void cache_pool::Clean()
{
	Lock lock(itsDeleteMutex);

	ASSERT(itsCacheLimit > 0);
	if (itsCache.size() <= static_cast<size_t>(itsCacheLimit))
	{
		return;
	}

	string oldestName;
	time_t oldestTime = INT_MAX;

	for (const auto& kv : itsCache)
	{
		if (kv.second.access_time < oldestTime && !kv.second.pinned)
		{
			oldestName = kv.first;
			oldestTime = kv.second.access_time;
		}
	}

	ASSERT(!oldestName.empty());

	itsCache.erase(oldestName);
	itsLogger.Trace("Data cleared from cache: " + oldestName +
	                " with time: " + boost::lexical_cast<string>(oldestTime));
	itsLogger.Trace("Cache size: " + boost::lexical_cast<string>(itsCache.size()));
}

shared_ptr<himan::info> cache_pool::GetInfo(const string& uniqueName)
{
	Lock lock(itsGetMutex);

	return make_shared<info>(*itsCache[uniqueName].info);
}

size_t cache_pool::Size() const { return itsCache.size(); }
<commit_msg>Remove erroneous comment<commit_after>/**
 * @file cache.cpp
 *
 */

#include "cache.h"
#include "info.h"
#include "logger.h"
#include "plugin_factory.h"
#include <boost/lexical_cast.hpp>
#include <time.h>

using namespace std;
using namespace himan::plugin;

typedef lock_guard<mutex> Lock;

std::mutex itsCheckMutex;

cache::cache() { itsLogger = logger("cache"); }
string cache::UniqueName(const info& info)
{
	string producer_id = boost::lexical_cast<string>(info.Producer().Id());
	string forecast_time = info.Time().OriginDateTime().String("%Y-%m-%d_%H:%M:%S");
	string valid_time = info.Time().ValidDateTime().String("%Y-%m-%d_%H:%M:%S");
	string param = info.Param().Name();
	string level_value = boost::lexical_cast<string>(info.Level().Value());
	string level = HPLevelTypeToString.at(info.Level().Type());
	string forecast_type = boost::lexical_cast<string>(info.ForecastType().Type());
	string forecast_type_value = boost::lexical_cast<string>(info.ForecastType().Value());
	return producer_id + '_' + forecast_time + '_' + valid_time + '_' + param + '_' + level + '_' + level_value + '_' +
	       forecast_type + '_' + forecast_type_value;
}

string cache::UniqueNameFromOptions(search_options& options)
{
	ASSERT(options.configuration->DatabaseType() == kNoDatabase || options.prod.Id() != kHPMissingInt);
	string producer_id = boost::lexical_cast<string>(options.prod.Id());
	string forecast_time = options.time.OriginDateTime().String("%Y-%m-%d_%H:%M:%S");
	string valid_time = options.time.ValidDateTime().String("%Y-%m-%d_%H:%M:%S");
	string param = options.param.Name();
	string level_value = boost::lexical_cast<string>((options.level).Value());
	string level = HPLevelTypeToString.at(options.level.Type());
	string forecast_type = boost::lexical_cast<string>(options.ftype.Type());
	string forecast_type_value = boost::lexical_cast<string>(options.ftype.Value());
	return producer_id + "_" + forecast_time + '_' + valid_time + '_' + param + '_' + level + '_' + level_value + '_' +
	       forecast_type + '_' + forecast_type_value;
}

void cache::Insert(info& anInfo, bool pin) { SplitToPool(anInfo, pin); }
void cache::SplitToPool(info& anInfo, bool pin)
{
	auto localInfo = anInfo;

	// Cached data is never replaced by another data that has
	// the same uniqueName

	string uniqueName = UniqueName(localInfo);

	{
		Lock lock(itsCheckMutex);

		if (cache_pool::Instance()->Find(uniqueName))
		{
			itsLogger.Trace("Data with key " + uniqueName + " already exists at cache");

			// Update timestamp of this cache item
			cache_pool::Instance()->UpdateTime(uniqueName);
			return;
		}
	}

#ifdef HAVE_CUDA
	if (localInfo.Grid()->IsPackedData())
	{
		itsLogger.Trace("Removing packed data from cached info");
		localInfo.Grid()->PackedData().Clear();
	}
#endif

	ASSERT(!localInfo.Grid()->IsPackedData());

	vector<param> params;
	vector<level> levels;
	vector<forecast_time> times;
	vector<forecast_type> ftype;

	params.push_back(localInfo.Param());
	levels.push_back(localInfo.Level());
	times.push_back(localInfo.Time());
	ftype.push_back(localInfo.ForecastType());

	auto newInfo = make_shared<info>(localInfo);

	newInfo->Params(params);
	newInfo->Levels(levels);
	newInfo->Times(times);
	newInfo->ForecastTypes(ftype);
	newInfo->Create(localInfo.Grid());

	ASSERT(uniqueName == UniqueName(*newInfo));

	{
		Lock lock(itsCheckMutex);
		cache_pool::Instance()->Insert(uniqueName, newInfo, pin);
	}
}

vector<shared_ptr<himan::info>> cache::GetInfo(search_options& options)
{
	string uniqueName = UniqueNameFromOptions(options);

	vector<shared_ptr<himan::info>> info;

	if (cache_pool::Instance()->Find(uniqueName))
	{
		info.push_back(cache_pool::Instance()->GetInfo(uniqueName));
		itsLogger.Trace("Found matching data for " + uniqueName);
	}

	return info;
}

void cache::Clean() { cache_pool::Instance()->Clean(); }
size_t cache::Size() const { return cache_pool::Instance()->Size(); }
cache_pool* cache_pool::itsInstance = NULL;

cache_pool::cache_pool() : itsCacheLimit(-1) { itsLogger = logger("cache_pool"); }

cache_pool* cache_pool::Instance()
{
	if (!itsInstance)
	{
		itsInstance = new cache_pool();
	}

	return itsInstance;
}

void cache_pool::CacheLimit(int theCacheLimit) { itsCacheLimit = theCacheLimit; }
bool cache_pool::Find(const string& uniqueName) { return itsCache.count(uniqueName) > 0; }
void cache_pool::Insert(const string& uniqueName, shared_ptr<himan::info> anInfo, bool pin)
{
	Lock lock(itsInsertMutex);

	cache_item item;
	item.info = anInfo;
	item.access_time = time(nullptr);
	item.pinned = pin;

	itsCache.insert(pair<string, cache_item>(uniqueName, item));
	itsLogger.Trace("Data added to cache with name: " + uniqueName + ", pinned: " + boost::lexical_cast<string>(pin));

	if (itsCacheLimit > -1 && itsCache.size() > static_cast<size_t>(itsCacheLimit))
	{
		Clean();
	}
}

void cache_pool::UpdateTime(const std::string& uniqueName) { itsCache[uniqueName].access_time = time(nullptr); }
void cache_pool::Clean()
{
	Lock lock(itsDeleteMutex);

	ASSERT(itsCacheLimit > 0);
	if (itsCache.size() <= static_cast<size_t>(itsCacheLimit))
	{
		return;
	}

	string oldestName;
	time_t oldestTime = INT_MAX;

	for (const auto& kv : itsCache)
	{
		if (kv.second.access_time < oldestTime && !kv.second.pinned)
		{
			oldestName = kv.first;
			oldestTime = kv.second.access_time;
		}
	}

	ASSERT(!oldestName.empty());

	itsCache.erase(oldestName);
	itsLogger.Trace("Data cleared from cache: " + oldestName +
	                " with time: " + boost::lexical_cast<string>(oldestTime));
	itsLogger.Trace("Cache size: " + boost::lexical_cast<string>(itsCache.size()));
}

shared_ptr<himan::info> cache_pool::GetInfo(const string& uniqueName)
{
	Lock lock(itsGetMutex);

	return make_shared<info>(*itsCache[uniqueName].info);
}

size_t cache_pool::Size() const { return itsCache.size(); }
<|endoftext|>


<commit_before>//=============================================================================
//
// Adventure Game Studio (AGS)
//
// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others
// The full list of copyright holders can be found in the Copyright.txt
// file, which is part of this source code distribution.
//
// The AGS source code is provided under the Artistic License 2.0.
// A copy of this license can be found in the file License.txt and at
// http://www.opensource.org/licenses/artistic-license-2.0.php
//
//=============================================================================

#include <stdio.h>
#include "ac/common.h"
#include "ac/display.h"
#include "ac/draw.h"
#include "ac/game.h"
#include "ac/gamesetupstruct.h"
#include "ac/gamestate.h"
#include "ac/global_drawingsurface.h"
#include "ac/global_translation.h"
#include "ac/roomstruct.h"
#include "ac/string.h"
#include "debug/debug_log.h"
#include "font/fonts.h"
#include "gui/guidefines.h"
#include "ac/spritecache.h"
#include "gfx/gfx_util.h"

using AGS::Common::Bitmap;
namespace BitmapHelper = AGS::Common::BitmapHelper;

extern Bitmap *raw_saved_screen;
extern roomstruct thisroom;
extern GameState play;
extern char lines[MAXLINE][200];
extern int  numlines;
extern int spritewidth[MAX_SPRITES],spriteheight[MAX_SPRITES];
extern SpriteCache spriteset;
extern GameSetupStruct game;
extern int current_screen_resolution_multiplier;

// Raw screen writing routines - similar to old CapturedStuff
//#define RAW_START() Bitmap *oldabuf=RAW_GRAPHICS()->GetBitmap(); RAW_GRAPHICS()->GetBitmap()=thisroom.ebscene[play.bg_frame]; play.raw_modified[play.bg_frame] = 1
//#define RAW_END() RAW_GRAPHICS()->GetBitmap() = oldabuf
#define RAW_START() raw_drawing_surface = thisroom.ebscene[play.bg_frame]; play.raw_modified[play.bg_frame] = 1
#define RAW_END()
#define RAW_SURFACE() (raw_drawing_surface)

Bitmap *raw_drawing_surface;

// RawSaveScreen: copy the current screen to a backup bitmap
void RawSaveScreen () {
    if (raw_saved_screen != NULL)
        delete raw_saved_screen;
    Bitmap *source = thisroom.ebscene[play.bg_frame];
    raw_saved_screen = BitmapHelper::CreateBitmapCopy(source);
}
// RawRestoreScreen: copy backup bitmap back to screen; we
// deliberately don't free the Bitmap *cos they can multiple restore
// and it gets freed on room exit anyway
void RawRestoreScreen() {
    if (raw_saved_screen == NULL) {
        debug_log("RawRestoreScreen: unable to restore, since the screen hasn't been saved previously.");
        return;
    }
    Bitmap *deston = thisroom.ebscene[play.bg_frame];
    deston->Blit(raw_saved_screen, 0, 0, 0, 0, deston->GetWidth(), deston->GetHeight());
    invalidate_screen();
    mark_current_background_dirty();
}
// Restores the backup bitmap, but tints it to the specified level
void RawRestoreScreenTinted(int red, int green, int blue, int opacity) {
    if (raw_saved_screen == NULL) {
        debug_log("RawRestoreScreenTinted: unable to restore, since the screen hasn't been saved previously.");
        return;
    }
    if ((red < 0) || (green < 0) || (blue < 0) ||
        (red > 255) || (green > 255) || (blue > 255) ||
        (opacity < 1) || (opacity > 100))
        quit("!RawRestoreScreenTinted: invalid parameter. R,G,B must be 0-255, opacity 1-100");

    DEBUG_CONSOLE("RawRestoreTinted RGB(%d,%d,%d) %d%%", red, green, blue, opacity);

    Bitmap *deston = thisroom.ebscene[play.bg_frame];
    tint_image(deston, raw_saved_screen, red, green, blue, opacity);
    invalidate_screen();
    mark_current_background_dirty();
}

void RawDrawFrameTransparent (int frame, int translev) {
    if ((frame < 0) || (frame >= thisroom.num_bscenes) ||
        (translev < 0) || (translev > 99))
        quit("!RawDrawFrameTransparent: invalid parameter (transparency must be 0-99, frame a valid BG frame)");

    if (thisroom.ebscene[frame]->GetColorDepth() <= 8)
        quit("!RawDrawFrameTransparent: 256-colour backgrounds not supported");

    if (frame == play.bg_frame)
        quit("!RawDrawFrameTransparent: cannot draw current background onto itself");

    if (translev == 0) {
        // just draw it over the top, no transparency
        thisroom.ebscene[play.bg_frame]->Blit(thisroom.ebscene[frame], 0, 0, 0, 0, thisroom.ebscene[frame]->GetWidth(), thisroom.ebscene[frame]->GetHeight());
        play.raw_modified[play.bg_frame] = 1;
        return;
    }
    // Draw it transparently
    RAW_START();
    AGS::Engine::GfxUtil::DrawSpriteWithTransparency (RAW_SURFACE(), thisroom.ebscene[frame], 0, 0,
        AGS::Engine::GfxUtil::Trans100ToAlpha255(translev));
    invalidate_screen();
    mark_current_background_dirty();
    RAW_END();
}

void RawClear (int clr) {
    play.raw_modified[play.bg_frame] = 1;
    clr = RAW_SURFACE()->GetCompatibleColor(clr);
    thisroom.ebscene[play.bg_frame]->Clear (clr);
    invalidate_screen();
    mark_current_background_dirty();
}
void RawSetColor (int clr) {
    //push_screen();
    //SetVirtualScreen(thisroom.ebscene[play.bg_frame]);
    // set the colour at the appropriate depth for the background
    play.raw_color = GetVirtualScreen()->GetCompatibleColor(clr);
    //pop_screen();
}
void RawSetColorRGB(int red, int grn, int blu) {
    if ((red < 0) || (red > 255) || (grn < 0) || (grn > 255) ||
        (blu < 0) || (blu > 255))
        quit("!RawSetColorRGB: colour values must be 0-255");

    play.raw_color = makecol_depth(thisroom.ebscene[play.bg_frame]->GetColorDepth(), red, grn, blu);
}
void RawPrint (int xx, int yy, const char*texx, ...) {
    char displbuf[STD_BUFFER_SIZE];
    va_list ap;
    va_start(ap,texx);
    vsprintf(displbuf, get_translation(texx), ap);
    va_end(ap);
    RAW_START();
    // don't use wtextcolor because it will do a 16->32 conversion
    color_t text_color = play.raw_color;
    if ((RAW_SURFACE()->GetColorDepth() <= 8) && (play.raw_color > 255)) {
        text_color = RAW_SURFACE()->GetCompatibleColor(1);
        debug_log ("RawPrint: Attempted to use hi-color on 256-col background");
    }
    multiply_up_coordinates(&xx, &yy);
    wouttext_outline(RAW_SURFACE(), xx, yy, play.normal_font, text_color, displbuf);
    // we must invalidate the entire screen because these are room
    // co-ordinates, not screen co-ords which it works with
    invalidate_screen();
    mark_current_background_dirty();
    RAW_END();
}
void RawPrintMessageWrapped (int xx, int yy, int wid, int font, int msgm) {
    char displbuf[3000];
    int texthit = wgetfontheight(font);
    multiply_up_coordinates(&xx, &yy);
    wid = multiply_up_coordinate(wid);

    get_message_text (msgm, displbuf);
    // it's probably too late but check anyway
    if (strlen(displbuf) > 2899)
        quit("!RawPrintMessageWrapped: message too long");
    break_up_text_into_lines (wid, font, displbuf);

    RAW_START();
    color_t text_color = play.raw_color;
    for (int i = 0; i < numlines; i++)
        wouttext_outline(RAW_SURFACE(), xx, yy + texthit*i, font, text_color, lines[i]);
    invalidate_screen();
    mark_current_background_dirty();
    RAW_END();
}

void RawDrawImageCore(int xx, int yy, int slot, int transparency) {
    if ((slot < 0) || (slot >= MAX_SPRITES) || (spriteset[slot] == NULL))
        quit("!RawDrawImage: invalid sprite slot number specified");
    RAW_START();

    if (spriteset[slot]->GetColorDepth() != RAW_SURFACE()->GetColorDepth()) {
        debug_log("RawDrawImage: Sprite %d colour depth %d-bit not same as background depth %d-bit", slot, spriteset[slot]->GetColorDepth(), RAW_SURFACE()->GetColorDepth());
    }

    draw_sprite_slot_support_alpha(RAW_SURFACE(), false, xx, yy, slot,
        AGS::Engine::GfxUtil::Trans100ToAlpha255(transparency));
    invalidate_screen();
    mark_current_background_dirty();
    RAW_END();
}

void RawDrawImage(int xx, int yy, int slot) {
    multiply_up_coordinates(&xx, &yy);
    RawDrawImageCore(xx, yy, slot);
}

void RawDrawImageTrans(int xx, int yy, int slot, int transparency) {
    multiply_up_coordinates(&xx, &yy);
    RawDrawImageCore(xx, yy, slot, transparency);
}

void RawDrawImageOffset(int xx, int yy, int slot) {

    if ((current_screen_resolution_multiplier == 1) && (game.default_resolution >= 3)) {
        // running a 640x400 game at 320x200, adjust
        xx /= 2;
        yy /= 2;
    }
    else if ((current_screen_resolution_multiplier > 1) && (game.default_resolution <= 2)) {
        // running a 320x200 game at 640x400, adjust
        xx *= 2;
        yy *= 2;
    }

    RawDrawImageCore(xx, yy, slot);
}

void RawDrawImageTransparent(int xx, int yy, int slot, int trans) {
    if ((trans < 0) || (trans > 100))
        quit("!RawDrawImageTransparent: invalid transparency setting");

    int trans_mode = (trans * 255) / 100;
    RawDrawImageTrans(xx, yy, slot, trans_mode);

    update_polled_stuff_if_runtime();  // this operation can be slow so stop music skipping
}
void RawDrawImageResized(int xx, int yy, int gotSlot, int width, int height) {
    if ((gotSlot < 0) || (gotSlot >= MAX_SPRITES) || (spriteset[gotSlot] == NULL))
        quit("!RawDrawImageResized: invalid sprite slot number specified");
    // very small, don't draw it
    if ((width < 1) || (height < 1))
        return;

    multiply_up_coordinates(&xx, &yy);
    multiply_up_coordinates(&width, &height);

    // resize the sprite to the requested size
    Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, spriteset[gotSlot]->GetColorDepth());
    newPic->StretchBlt(spriteset[gotSlot],
        RectWH(0, 0, spritewidth[gotSlot], spriteheight[gotSlot]),
        RectWH(0, 0, width, height));

    RAW_START();
    if (newPic->GetColorDepth() != RAW_SURFACE()->GetColorDepth())
        quit("!RawDrawImageResized: image colour depth mismatch: the background image must have the same colour depth as the sprite being drawn");

    AGS::Engine::GfxUtil::DrawSpriteWithTransparency(RAW_SURFACE(), newPic, xx, yy);
    delete newPic;
    invalidate_screen();
    mark_current_background_dirty();
    update_polled_stuff_if_runtime();  // this operation can be slow so stop music skipping
    RAW_END();
}
void RawDrawLine (int fromx, int fromy, int tox, int toy) {
    multiply_up_coordinates(&fromx, &fromy);
    multiply_up_coordinates(&tox, &toy);

    play.raw_modified[play.bg_frame] = 1;
    int ii,jj;
    // draw a line thick enough to look the same at all resolutions
    Bitmap *bg_frame = thisroom.ebscene[play.bg_frame];
    color_t draw_color = play.raw_color;
    for (ii = 0; ii < get_fixed_pixel_size(1); ii++) {
        for (jj = 0; jj < get_fixed_pixel_size(1); jj++)
            bg_frame->DrawLine (Line(fromx+ii, fromy+jj, tox+ii, toy+jj), draw_color);
    }
    invalidate_screen();
    mark_current_background_dirty();
}
void RawDrawCircle (int xx, int yy, int rad) {
    multiply_up_coordinates(&xx, &yy);
    rad = multiply_up_coordinate(rad);

    play.raw_modified[play.bg_frame] = 1;
    Bitmap *bg_frame = thisroom.ebscene[play.bg_frame];
    bg_frame->FillCircle(Circle (xx, yy, rad), play.raw_color);
    invalidate_screen();
    mark_current_background_dirty();
}
void RawDrawRectangle(int x1, int y1, int x2, int y2) {
    play.raw_modified[play.bg_frame] = 1;
    multiply_up_coordinates(&x1, &y1);
    multiply_up_coordinates_round_up(&x2, &y2);

    Bitmap *bg_frame = thisroom.ebscene[play.bg_frame];
    bg_frame->FillRect(Rect(x1,y1,x2,y2), play.raw_color);
    invalidate_screen();
    mark_current_background_dirty();
}
void RawDrawTriangle(int x1, int y1, int x2, int y2, int x3, int y3) {
    play.raw_modified[play.bg_frame] = 1;
    multiply_up_coordinates(&x1, &y1);
    multiply_up_coordinates(&x2, &y2);
    multiply_up_coordinates(&x3, &y3);

    Bitmap *bg_frame = thisroom.ebscene[play.bg_frame];
    bg_frame->DrawTriangle(Triangle (x1,y1,x2,y2,x3,y3), play.raw_color);
    invalidate_screen();
    mark_current_background_dirty();
}
<commit_msg>Engine: fixed crash in RawClearScreen()<commit_after>//=============================================================================
//
// Adventure Game Studio (AGS)
//
// Copyright (C) 1999-2011 Chris Jones and 2011-20xx others
// The full list of copyright holders can be found in the Copyright.txt
// file, which is part of this source code distribution.
//
// The AGS source code is provided under the Artistic License 2.0.
// A copy of this license can be found in the file License.txt and at
// http://www.opensource.org/licenses/artistic-license-2.0.php
//
//=============================================================================

#include <stdio.h>
#include "ac/common.h"
#include "ac/display.h"
#include "ac/draw.h"
#include "ac/game.h"
#include "ac/gamesetupstruct.h"
#include "ac/gamestate.h"
#include "ac/global_drawingsurface.h"
#include "ac/global_translation.h"
#include "ac/roomstruct.h"
#include "ac/string.h"
#include "debug/debug_log.h"
#include "font/fonts.h"
#include "gui/guidefines.h"
#include "ac/spritecache.h"
#include "gfx/gfx_util.h"

using AGS::Common::Bitmap;
namespace BitmapHelper = AGS::Common::BitmapHelper;

extern Bitmap *raw_saved_screen;
extern roomstruct thisroom;
extern GameState play;
extern char lines[MAXLINE][200];
extern int  numlines;
extern int spritewidth[MAX_SPRITES],spriteheight[MAX_SPRITES];
extern SpriteCache spriteset;
extern GameSetupStruct game;
extern int current_screen_resolution_multiplier;

// Raw screen writing routines - similar to old CapturedStuff
//#define RAW_START() Bitmap *oldabuf=RAW_GRAPHICS()->GetBitmap(); RAW_GRAPHICS()->GetBitmap()=thisroom.ebscene[play.bg_frame]; play.raw_modified[play.bg_frame] = 1
//#define RAW_END() RAW_GRAPHICS()->GetBitmap() = oldabuf
#define RAW_START() raw_drawing_surface = thisroom.ebscene[play.bg_frame]; play.raw_modified[play.bg_frame] = 1
#define RAW_END()
#define RAW_SURFACE() (raw_drawing_surface)

Bitmap *raw_drawing_surface;

// RawSaveScreen: copy the current screen to a backup bitmap
void RawSaveScreen () {
    if (raw_saved_screen != NULL)
        delete raw_saved_screen;
    Bitmap *source = thisroom.ebscene[play.bg_frame];
    raw_saved_screen = BitmapHelper::CreateBitmapCopy(source);
}
// RawRestoreScreen: copy backup bitmap back to screen; we
// deliberately don't free the Bitmap *cos they can multiple restore
// and it gets freed on room exit anyway
void RawRestoreScreen() {
    if (raw_saved_screen == NULL) {
        debug_log("RawRestoreScreen: unable to restore, since the screen hasn't been saved previously.");
        return;
    }
    Bitmap *deston = thisroom.ebscene[play.bg_frame];
    deston->Blit(raw_saved_screen, 0, 0, 0, 0, deston->GetWidth(), deston->GetHeight());
    invalidate_screen();
    mark_current_background_dirty();
}
// Restores the backup bitmap, but tints it to the specified level
void RawRestoreScreenTinted(int red, int green, int blue, int opacity) {
    if (raw_saved_screen == NULL) {
        debug_log("RawRestoreScreenTinted: unable to restore, since the screen hasn't been saved previously.");
        return;
    }
    if ((red < 0) || (green < 0) || (blue < 0) ||
        (red > 255) || (green > 255) || (blue > 255) ||
        (opacity < 1) || (opacity > 100))
        quit("!RawRestoreScreenTinted: invalid parameter. R,G,B must be 0-255, opacity 1-100");

    DEBUG_CONSOLE("RawRestoreTinted RGB(%d,%d,%d) %d%%", red, green, blue, opacity);

    Bitmap *deston = thisroom.ebscene[play.bg_frame];
    tint_image(deston, raw_saved_screen, red, green, blue, opacity);
    invalidate_screen();
    mark_current_background_dirty();
}

void RawDrawFrameTransparent (int frame, int translev) {
    if ((frame < 0) || (frame >= thisroom.num_bscenes) ||
        (translev < 0) || (translev > 99))
        quit("!RawDrawFrameTransparent: invalid parameter (transparency must be 0-99, frame a valid BG frame)");

    if (thisroom.ebscene[frame]->GetColorDepth() <= 8)
        quit("!RawDrawFrameTransparent: 256-colour backgrounds not supported");

    if (frame == play.bg_frame)
        quit("!RawDrawFrameTransparent: cannot draw current background onto itself");

    RAW_START();
    if (translev == 0)
    {
        // just draw it over the top, no transparency
        RAW_SURFACE()->Blit(thisroom.ebscene[frame], 0, 0, 0, 0, thisroom.ebscene[frame]->GetWidth(), thisroom.ebscene[frame]->GetHeight());
    }
    else
    {
        // Draw it transparently
        AGS::Engine::GfxUtil::DrawSpriteWithTransparency (RAW_SURFACE(), thisroom.ebscene[frame], 0, 0,
            AGS::Engine::GfxUtil::Trans100ToAlpha255(translev));
    }
    invalidate_screen();
    mark_current_background_dirty();
    RAW_END();
}

void RawClear (int clr) {
    RAW_START();
    clr = RAW_SURFACE()->GetCompatibleColor(clr);
    RAW_SURFACE()->Clear (clr);
    invalidate_screen();
    mark_current_background_dirty();
}
void RawSetColor (int clr) {
    //push_screen();
    //SetVirtualScreen(thisroom.ebscene[play.bg_frame]);
    // set the colour at the appropriate depth for the background
    play.raw_color = GetVirtualScreen()->GetCompatibleColor(clr);
    //pop_screen();
}
void RawSetColorRGB(int red, int grn, int blu) {
    if ((red < 0) || (red > 255) || (grn < 0) || (grn > 255) ||
        (blu < 0) || (blu > 255))
        quit("!RawSetColorRGB: colour values must be 0-255");

    play.raw_color = makecol_depth(thisroom.ebscene[play.bg_frame]->GetColorDepth(), red, grn, blu);
}
void RawPrint (int xx, int yy, const char*texx, ...) {
    char displbuf[STD_BUFFER_SIZE];
    va_list ap;
    va_start(ap,texx);
    vsprintf(displbuf, get_translation(texx), ap);
    va_end(ap);
    RAW_START();
    // don't use wtextcolor because it will do a 16->32 conversion
    color_t text_color = play.raw_color;
    if ((RAW_SURFACE()->GetColorDepth() <= 8) && (play.raw_color > 255)) {
        text_color = RAW_SURFACE()->GetCompatibleColor(1);
        debug_log ("RawPrint: Attempted to use hi-color on 256-col background");
    }
    multiply_up_coordinates(&xx, &yy);
    wouttext_outline(RAW_SURFACE(), xx, yy, play.normal_font, text_color, displbuf);
    // we must invalidate the entire screen because these are room
    // co-ordinates, not screen co-ords which it works with
    invalidate_screen();
    mark_current_background_dirty();
    RAW_END();
}
void RawPrintMessageWrapped (int xx, int yy, int wid, int font, int msgm) {
    char displbuf[3000];
    int texthit = wgetfontheight(font);
    multiply_up_coordinates(&xx, &yy);
    wid = multiply_up_coordinate(wid);

    get_message_text (msgm, displbuf);
    // it's probably too late but check anyway
    if (strlen(displbuf) > 2899)
        quit("!RawPrintMessageWrapped: message too long");
    break_up_text_into_lines (wid, font, displbuf);

    RAW_START();
    color_t text_color = play.raw_color;
    for (int i = 0; i < numlines; i++)
        wouttext_outline(RAW_SURFACE(), xx, yy + texthit*i, font, text_color, lines[i]);
    invalidate_screen();
    mark_current_background_dirty();
    RAW_END();
}

void RawDrawImageCore(int xx, int yy, int slot, int transparency) {
    if ((slot < 0) || (slot >= MAX_SPRITES) || (spriteset[slot] == NULL))
        quit("!RawDrawImage: invalid sprite slot number specified");
    RAW_START();

    if (spriteset[slot]->GetColorDepth() != RAW_SURFACE()->GetColorDepth()) {
        debug_log("RawDrawImage: Sprite %d colour depth %d-bit not same as background depth %d-bit", slot, spriteset[slot]->GetColorDepth(), RAW_SURFACE()->GetColorDepth());
    }

    draw_sprite_slot_support_alpha(RAW_SURFACE(), false, xx, yy, slot,
        AGS::Engine::GfxUtil::Trans100ToAlpha255(transparency));
    invalidate_screen();
    mark_current_background_dirty();
    RAW_END();
}

void RawDrawImage(int xx, int yy, int slot) {
    multiply_up_coordinates(&xx, &yy);
    RawDrawImageCore(xx, yy, slot);
}

void RawDrawImageTrans(int xx, int yy, int slot, int transparency) {
    multiply_up_coordinates(&xx, &yy);
    RawDrawImageCore(xx, yy, slot, transparency);
}

void RawDrawImageOffset(int xx, int yy, int slot) {

    if ((current_screen_resolution_multiplier == 1) && (game.default_resolution >= 3)) {
        // running a 640x400 game at 320x200, adjust
        xx /= 2;
        yy /= 2;
    }
    else if ((current_screen_resolution_multiplier > 1) && (game.default_resolution <= 2)) {
        // running a 320x200 game at 640x400, adjust
        xx *= 2;
        yy *= 2;
    }

    RawDrawImageCore(xx, yy, slot);
}

void RawDrawImageTransparent(int xx, int yy, int slot, int trans) {
    if ((trans < 0) || (trans > 100))
        quit("!RawDrawImageTransparent: invalid transparency setting");

    int trans_mode = (trans * 255) / 100;
    RawDrawImageTrans(xx, yy, slot, trans_mode);

    update_polled_stuff_if_runtime();  // this operation can be slow so stop music skipping
}
void RawDrawImageResized(int xx, int yy, int gotSlot, int width, int height) {
    if ((gotSlot < 0) || (gotSlot >= MAX_SPRITES) || (spriteset[gotSlot] == NULL))
        quit("!RawDrawImageResized: invalid sprite slot number specified");
    // very small, don't draw it
    if ((width < 1) || (height < 1))
        return;

    multiply_up_coordinates(&xx, &yy);
    multiply_up_coordinates(&width, &height);

    // resize the sprite to the requested size
    Bitmap *newPic = BitmapHelper::CreateBitmap(width, height, spriteset[gotSlot]->GetColorDepth());
    newPic->StretchBlt(spriteset[gotSlot],
        RectWH(0, 0, spritewidth[gotSlot], spriteheight[gotSlot]),
        RectWH(0, 0, width, height));

    RAW_START();
    if (newPic->GetColorDepth() != RAW_SURFACE()->GetColorDepth())
        quit("!RawDrawImageResized: image colour depth mismatch: the background image must have the same colour depth as the sprite being drawn");

    AGS::Engine::GfxUtil::DrawSpriteWithTransparency(RAW_SURFACE(), newPic, xx, yy);
    delete newPic;
    invalidate_screen();
    mark_current_background_dirty();
    update_polled_stuff_if_runtime();  // this operation can be slow so stop music skipping
    RAW_END();
}
void RawDrawLine (int fromx, int fromy, int tox, int toy) {
    multiply_up_coordinates(&fromx, &fromy);
    multiply_up_coordinates(&tox, &toy);

    play.raw_modified[play.bg_frame] = 1;
    int ii,jj;
    // draw a line thick enough to look the same at all resolutions
    Bitmap *bg_frame = thisroom.ebscene[play.bg_frame];
    color_t draw_color = play.raw_color;
    for (ii = 0; ii < get_fixed_pixel_size(1); ii++) {
        for (jj = 0; jj < get_fixed_pixel_size(1); jj++)
            bg_frame->DrawLine (Line(fromx+ii, fromy+jj, tox+ii, toy+jj), draw_color);
    }
    invalidate_screen();
    mark_current_background_dirty();
}
void RawDrawCircle (int xx, int yy, int rad) {
    multiply_up_coordinates(&xx, &yy);
    rad = multiply_up_coordinate(rad);

    play.raw_modified[play.bg_frame] = 1;
    Bitmap *bg_frame = thisroom.ebscene[play.bg_frame];
    bg_frame->FillCircle(Circle (xx, yy, rad), play.raw_color);
    invalidate_screen();
    mark_current_background_dirty();
}
void RawDrawRectangle(int x1, int y1, int x2, int y2) {
    play.raw_modified[play.bg_frame] = 1;
    multiply_up_coordinates(&x1, &y1);
    multiply_up_coordinates_round_up(&x2, &y2);

    Bitmap *bg_frame = thisroom.ebscene[play.bg_frame];
    bg_frame->FillRect(Rect(x1,y1,x2,y2), play.raw_color);
    invalidate_screen();
    mark_current_background_dirty();
}
void RawDrawTriangle(int x1, int y1, int x2, int y2, int x3, int y3) {
    play.raw_modified[play.bg_frame] = 1;
    multiply_up_coordinates(&x1, &y1);
    multiply_up_coordinates(&x2, &y2);
    multiply_up_coordinates(&x3, &y3);

    Bitmap *bg_frame = thisroom.ebscene[play.bg_frame];
    bg_frame->DrawTriangle(Triangle (x1,y1,x2,y2,x3,y3), play.raw_color);
    invalidate_screen();
    mark_current_background_dirty();
}
<|endoftext|>


<commit_before>#ifndef __LIB_IMENUCONTROL_HPP__
#define __LIB_IMENUCONTROL_HPP__

#include <lib/draw/rendergroup.hpp>
#include <lib/include/key.hpp>
#include <lib/include/color.hpp>
#include "menumanager.hpp"
#include <lib/draw/scene.hpp>

namespace lib
{
	namespace menu
	{
		class IMenuControl : public lib::draw::RenderGroup
		{
		public:

			IMenuControl(const std::string &name) : lib::draw::RenderGroup(name) {}
			virtual ~IMenuControl() {}
			virtual void onKeyPressed(lib::input::Key key) = 0;
			virtual void onKeyReleased(lib::input::Key key) = 0;
			MenuManager * const menuManager() const
			{
				return dynamic_cast<MenuManager*const>(parent());
			}

			uptr<MenuTheme> const &menuTheme() const
			{
				return menuManager()->menuTheme();
			}
		};
	}
}

#endif
<commit_msg>Manager getter<commit_after>#ifndef __LIB_IMENUCONTROL_HPP__
#define __LIB_IMENUCONTROL_HPP__

#include <lib/draw/rendergroup.hpp>
#include <lib/include/key.hpp>
#include <lib/include/color.hpp>
#include "menumanager.hpp"
#include <lib/draw/scene.hpp>

namespace lib
{
	namespace menu
	{
		class IMenuControl : public lib::draw::RenderGroup
		{
		public:

			IMenuControl(const std::string &name) : lib::draw::RenderGroup(name) {}
			virtual ~IMenuControl() {}
			virtual void onKeyPressed(lib::input::Key key) = 0;
			virtual void onKeyReleased(lib::input::Key key) = 0;
			MenuManager * const menuManager()
			{
				return dynamic_cast<MenuManager *const>(parentScene());
			}

			uptr<MenuTheme> const &menuTheme()
			{
				return menuManager()->menuTheme();
			}
		};
	}
}

#endif
<|endoftext|>


<commit_before>#include "gpu_buffer.hpp"
#include "glfunctions.hpp"

#include "../base/assert.hpp"

glConst glTarget(GPUBuffer::Target t)
{
  if (t == GPUBuffer::ElementBuffer)
    return GLConst::GLArrayBuffer;

  return GLConst::GLElementArrayBuffer;
}

GPUBuffer::GPUBuffer(Target t, uint8_t elementSize, uint16_t capacity)
  : base_t(elementSize, capacity)
  , m_t(t)
{
  m_bufferID = GLFunctions::glGenBuffer();
  Bind();
  Resize(capacity);
}

GPUBuffer::~GPUBuffer()
{
  GLFunctions::glDeleteBuffer(m_bufferID);
}

void GPUBuffer::UploadData(void const * data, uint16_t elementCount)
{
  uint16_t currentSize = GetCurrentSize();
  uint8_t elementSize = GetElementSize();
  ASSERT(GetCapacity() >= elementCount + currentSize, ("Not enough memory to upload ", elementCount, " elements"));
  Bind();
  GLFunctions::glBufferSubData(glTarget(m_t), elementCount * elementSize, data, currentSize * elementSize);
  base_t::UploadData(elementCount);
}

void GPUBuffer::Bind()
{
  GLFunctions::glBindBuffer(m_bufferID, glTarget((m_t)));
}

void GPUBuffer::Resize(uint16_t elementCount)
{
  base_t::Resize(elementCount);
  GLFunctions::glBufferData(glTarget(m_t), GetCapacity() * GetElementSize(), NULL, GLConst::GLStaticDraw);
}
<commit_msg>[drape] on update Index buffer we must bind it as current<commit_after>#include "gpu_buffer.hpp"
#include "glfunctions.hpp"

#include "../base/assert.hpp"

glConst glTarget(GPUBuffer::Target t)
{
  if (t == GPUBuffer::ElementBuffer)
    return GLConst::GLArrayBuffer;

  return GLConst::GLElementArrayBuffer;
}

GPUBuffer::GPUBuffer(Target t, uint8_t elementSize, uint16_t capacity)
  : base_t(elementSize, capacity)
  , m_t(t)
{
  m_bufferID = GLFunctions::glGenBuffer();
  Bind();
  Resize(capacity);
}

GPUBuffer::~GPUBuffer()
{
  GLFunctions::glDeleteBuffer(m_bufferID);
}

void GPUBuffer::UploadData(void const * data, uint16_t elementCount)
{
  uint16_t currentSize = GetCurrentSize();
  uint8_t elementSize = GetElementSize();
  ASSERT(GetCapacity() >= elementCount + currentSize, ("Not enough memory to upload ", elementCount, " elements"));
  Bind();
  GLFunctions::glBufferSubData(glTarget(m_t), elementCount * elementSize, data, currentSize * elementSize);
  base_t::UploadData(elementCount);
}

void GPUBuffer::Bind()
{
  GLFunctions::glBindBuffer(m_bufferID, glTarget((m_t)));
}

void GPUBuffer::Resize(uint16_t elementCount)
{
  base_t::Resize(elementCount);
  Bind();
  GLFunctions::glBufferData(glTarget(m_t), GetCapacity() * GetElementSize(), NULL, GLConst::GLStaticDraw);
}
<|endoftext|>